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
迫使你分離標籤,達到更高的可用性