【发布时间】:2018-08-20 12:13:17
【问题描述】:
react 和 redux 还是新手,我一直在开发 MERN 用户注册应用程序,我现在正在工作。
在 redux 文档中,我发现创建者建议在将 redux 与 react 集成时将其代码分成两种类型的组件:Presentational(关注事物的外观)和 Container(关注事物的工作方式)。见https://redux.js.org/basics/usagewithreact。
我认为这样可以更好地管理应用程序并提高可扩展性。
对于不熟悉的人,这里对优点进行了很好的解释:https://www.youtube.com/watch?v=NazjKgJp7sQ
我只是在以这种方式掌握概念和重写代码方面挣扎。
这是我编写的用于显示用户创建的 cmets 的帖子组件的示例。它在作为道具传递的更高级别组件中接收来自帖子的数据。作为回报,我将所有标记都应用了引导样式。我正在订阅我通过创建事件处理程序导入和使用的 redux 操作。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import classnames from 'classnames';
import { Link } from 'react-router-dom';
import { deletePost, addLike, removeLike } from '../../actions/postActions';
class PostItem extends Component {
onDeleteClick(id) {
this.props.deletePost(id);
}
onLikeClick(id) {
this.props.addLike(id);
}
onUnlikeClick(id) {
this.props.removeLike(id);
}
findUserLike(likes) {
const { auth } = this.props;
if (likes.filter(like => like.user === auth.user.id).length > 0) {
return true;
} else {
return false;
}
}
render() {
const { post, auth, showActions } = this.props;
return (
<div className="card card-body mb-3">
<div className="row">
<div className="col-md-2">
<a href="profile.html">
<img
className="rounded-circle d-none d-md-block"
src={post.avatar}
alt=""
/>
</a>
<br />
<p className="text-center">{post.name}</p>
</div>
<div className="col-md-10">
<p className="lead">{post.text}</p>
{showActions ? (
<span>
<button
onClick={this.onLikeClick.bind(this, post._id)}
type="button"
className="btn btn-light mr-1"
>
<i
className={classnames('fas fa-thumbs-up', {
'text-info': this.findUserLike(post.likes)
})}
/>
<span className="badge badge-light">{post.likes.length}</span>
</button>
<button
onClick={this.onUnlikeClick.bind(this, post._id)}
type="button"
className="btn btn-light mr-1"
>
<i className="text-secondary fas fa-thumbs-down" />
</button>
<Link to={`/post/${post._id}`} className="btn btn-info mr-1">
Comments
</Link>
{post.user === auth.user.id ? (
<button
onClick={this.onDeleteClick.bind(this, post._id)}
type="button"
className="btn btn-danger mr-1"
>
<i className="fas fa-times" />
</button>
) : null}
</span>
) : null}
</div>
</div>
</div>
);
}
}
PostItem.defaultProps = {
showActions: true,
};
PostItem.propTypes = {
deletePost: PropTypes.func.isRequired,
addLike: PropTypes.func.isRequired,
removeLike: PropTypes.func.isRequired,
post: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
auth: state.auth,
});
export default connect(mapStateToProps, { deletePost, addLike, removeLike })(PostItem);
如您所见,代码不像我希望的那样简洁紧凑。我的目标是让展示组件不知道 redux,并在此处进行所有样式设置和引导工作,而容器组件具有 redux 和连接功能。有谁知道我应该如何处理这个问题?
我看到人们使用 connect 将这些类型的组件链接在一起:
const PostItemContainer = connect(
mapStateToProps,
{ deletePost, addLike, removeLike }
)(PostItem);
export default PostItemContainer;
但我不知道如何在实践中实现这一点。 如果您能帮我解释并提供一些示例代码,那将是非常棒的。
提前致谢!
【问题讨论】:
-
@jsDevia 的回答很好,虽然我不会为小型应用程序使用
onClick的箭头功能,但我认为这对小型应用程序来说不是问题。我想知道,你的Post组件连接到 Redux 了吗? -
是的,我的 Post 组件也连接到了 redux。您是否建议只将最高级别的组件连接到 redux?
-
如果这个组件可以是所有其他展示组件的容器组件,是的,我可以建议。 @jsDevia 的回答与此逻辑类似,但他为此使用了另一个组件。但是,您已经有一个
Post组件,并且它已连接到 Redux。
标签: javascript reactjs react-redux components mern