(翻譯)React Container Components


原文:Container Components

Container Components

在 React 模式上對我的代碼有最深遠影響的一個模式叫 container component 模式。

在 React.js Conf 上,Jason Bonta 和我們講了他們在Facebook上是如何建立高性能組件(High Performance Components)。Nestled 在這個演講中講的就是 this gem about container components

這個概念很簡單:

一個 container 只是做數據拉取然后渲染與它的 corresponding 子組件。就是這樣。

“Corresponding” 意味着分享同一個名稱的組件,例如:

StockWidgetContainer => StockWidget
TagCloudContainer => TagCloud
PartyPooperListContainer => PartyPooperList

這就是其中的概念。

Why containers?

比如你有一個用於展示評論的組件。你並不知道有關 container 組件。所以,你會將所有東西都放在一個地方。

//  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});
            }.bind(this)
        });
    }

    render(){
        return <ul> {this.state.comments.map(renderComponent)} </ul>;
    }

    renderComponent({body, author}){
        return <li> {body}-{author} </li>;
    }
}

你的組件就是用於拉取數據並展示它。這並沒有什么"錯誤",但是你卻錯過了一些React的優點。

可復用性

CommentList組件除了在同一精確的條件情況下才能復用。

數據結構

你希望的組件應該規定他們需要的數據類型的預期。PropTypes正是干這個的。

我們的組件對數據結構要求很高但是沒有辦法說出這些要求。如果json的接口數據改變了,這個組件會不做出任何提示出錯。(其實想說的就是,無法好好利用PropTypes來把控數據結構是否正確)

再來一次。這一次加上container

首先,讓我們將數據拉取的功能移到 container 組件上。

// 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} />;
  }
}

現在,我們將comments作為CommentList的prop重制一遍。

// 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並且一旦出錯便會提示。

我是一個 container components 的大粉絲。他們讓我的 React game 進步了很多,並且使我的組件更容易去閱讀。嘗試一下他們,並看一下Jason的演講。太棒了!

Carry on, nerds.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM