Redux 的 React 绑定库包含了 容器组件和展现组件相分离 的开发思想。明智的作法是只在最顶层组件(如路由操做)里使用 Redux。其他内部组件仅仅是展现性的,全部数据都经过 props 传入。css
那么为何须要容器组件和展现组件相分离呢?ajax
这里有个基本原则:容器组件仅仅作数据提取,而后渲染对应的子组件,记住这个点,Trust me!json
看下面这个展现列表的例子,不区分容器和展现组件的状况性能优化
// CommentList.js class CommentList extends React.Component { constructor() { super(); this.state = { comments: [] } } componentDidMount() { $.ajax({ url: "/my-comments.json", dataType: 'json', success: function(comments) { this.setState({comments: comments}); }.bind(this) }); } render() { return <ul> {this.state.comments.map(renderComment)} </ul>; } renderComment({body, author}) { return <li>{body}—{author}</li>; } }
可用性:CommentList不能够复用数据结构
数据结构:组件应该对所须要的数据有所预期,但这里其实没有,PropTypes能够很好的作到这一点性能
那么来看下分离的状况:优化
// CommentListContainer.js class CommentListContainer extends React.Component { constructor() { super(); this.state = { comments: [] } } componentDidMount() { $.ajax({ url: "/my-comments.json", dataType: 'json', success: function(comments) { this.setState({comments: comments}); }.bind(this) }); } render() { return <CommentList comments={this.state.comments} />; } } // CommentList.js class CommentList extends React.Component { constructor(props) { super(props); } render() { return <ul> {this.props.comments.map(renderComment)} </ul>; } renderComment({body, author}) { return <li>{body}—{author}</li>; } }
这样就作到了数据提取和渲染分离,CommentList能够复用,CommentList能够设置PropTypes判断数据的可用性this
来看下容器组件和展现组件的区别:url
展现组件 | 容器组件 |
---|---|
关注事物的展现 | 关注事物如何工做 |
可能包含展现和容器组件,而且通常会有DOM标签和css样式 | 可能包含展现和容器组件,而且不会有DOM标签和css样式 |
经常容许经过this.props.children传递 | 提供数据和行为给容器组件或者展现组件 |
对第三方没有任何依赖,好比store 或者 flux action | 调用flux action 而且提供他们的回调给展现组件 |
不要指定数据如何加载和变化 | 做为数据源,一般采用较高阶的组件,而不是本身写,好比React Redux的connect(), Relay的createContainer(), Flux Utils的Container.create() |
仅经过属性获取数据和回调 | |
不多有本身的状态,即便有,也是本身的UI状态 | |
除非他们须要的本身的状态,生命周期,或性能优化才会被写为功能组件 |
优点:设计
展现和容器更好的分离,更好的理解应用程序和UI
重用性高,展现组件能够用于多个不一样的state数据源
展现组件就是你的调色板,能够把他们放到单独的页面,在不影响应用程序的状况下,让设计师调整UI
迫使你分离标签,达到更高的可用性