1. 程式人生 > >【譯】容器元件 (Container Components)

【譯】容器元件 (Container Components)

medium 原文連結

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

Jason Bonta 講了如何建立高效能元件(High Performance Components),這個演講講的就是 container components

這個概念非常簡單:

一個 container 僅僅只是做資料拉取然後渲染它對應的子元件。

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

(StockWidgetContainer) => StockWidget;
(TagCloudContainer
) =>
TagCloud; (PartyPooperListContainer) => PartyPooperList; 複製程式碼

這就是其中的概念。

Why containers?

假設你有一個用於展示評論的元件。在你不使用 container 元件的時候,你會把所有程式碼都放在一個地方:

class CommentList extends React.Component {
  this.state = { comments: [] };

  componentDidMount() {
    fetchSomeComments(comments =>
      this
.setState({ comments: comments })); } render() { return ( <ul> {this.state.comments.map(c => ( <li>{c.body}—{c.author}</li> ))} </ul> ); } } 複製程式碼

你的元件就是用於拉取資料並展示它。這並沒有什麼錯,但是你錯過了一些 React 的優點。

可複用性 (Reusability)

除非在完全相同的情況下,否則CommentList

元件無法被複用。

資料結構(Data structure)

你的標記元件應該給出他們所期望的資料型別。PropTypes就是做這個的。

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

再一次,這次用一個 container (Once again. This time with a container)

首先,我們把資料拉取的功能放到 container 元件上。

class CommentListContainer extends React.Component {
  state = {
    comments: []
  };

  componentDidMount() {
    fetchSomeComments((comments) => this.setState({ comments: comments }));
  }

  render() {
    return <CommentList comments={this.state.comments} />;
  }
}
複製程式碼

現在,我們修改CommentList讓它接收comments 作為prop

const CommentList = (props) => (
  <ul>
    {props.comments.map((c) => (
      <li>
        {c.body}—{c.author}
      </li>
    ))}
  </ul>
);
複製程式碼

最後,我們得到了什麼?(So, what did we get?)

我們實際上得到了很多...

我們分離了資料拉取和渲染(data-fetching and rendering)。

我們使我們的 CommentList 元件得以複用。

我們賦予了CommentList設定PropTypes和錯誤提示的能力。

我是一個container components的大粉絲。他們讓我的 React game 有了很大的進步,並且使我的元件更加易讀。試試,看看 Jason 的演講。太棒了!

Carry on, nerds.

——完——