React 組件模式

來源:互聯網
上載者:User

簡評:組件(component)是 React 的核心,瞭解它們有助於構建好的設計結構。

什麼是組件(component)

組件運行你將 UI 拆分為獨立的可重用的部分。和 JavaScript 函數類似,組件接收名為 props 的輸入並返回 React 元素,它描述(聲明)使用者介面應該是什麼樣子的。這就是 React 被稱為聲明性 API 的原因,你只需要聲明你希望得到的 UI ,之後 React 負責具體的細節。

組件 API

當安裝 React 後,便可以使用 React 提供的 API,基本可以分成 5 種。

  • render
  • state
  • props
  • context
  • lifecycle events

雖然組件可以使用所有的 API,但是通常一個組件只使用部分的 API,我們可以對使用不同 API 的組件進行細分,分成有狀態(stateful) 和無狀態(stateless) 兩種組件。

  • 有狀態組件使用(render,state 和 生命週期相關事件)
  • 無狀態組件使用 (render,props 和 context)

這樣將資料邏輯和 UI 表現層進行分離,通過組件之間劃分職責可以建立更多可重用的組件,在構建可擴充的應用程式時尤為重要。

組件模式

通常組件模式有以下幾種:

  • Container
  • Presentational
  • 高階組件(Higher order components 【HOC’s】)
  • Render callback

container

容器組件(container component )負責擷取資料然後渲染部分交給相應的子組件來負責。

容器是你的資料或邏輯層並利用 stateful API,使用生命週期事件你可以串連 state 到 redux 或 flux 的 storage 中。在容器組件的 render 方法中,你可以使用 Presentational 組件來渲染具體的樣式。

注意:由於容器組件需要使用 stateful api ,所以容器組件需要定義成類而不能是一個純函數。

我們來定義一個 組件 Greeting,他具有狀態,生命週期 componentDidMount 事件 和 render 方法。

class Greeting extends React.Component {  constructor() {    super();    this.state = {      name: "",    };  }  componentDidMount() {    // AJAX    this.setState(() => {      return {        name: "William",      };    });  }  render() {    return (      <div>        <h1>Hello! {this.state.name}</h1>      </div>    );  }}

現在我們對 Greeting 進行改進,將其分離成容器組件(container component)和展示組件(presentational component)。

Presentational

Presentational components 使用 props,render,和 context (stateless API's) ,並且由於不需要使用生命週期相關api,我們可以使用純函數來簡化表述它們:

const GreetingCard = (props) => {  return (    <div>      <h1>Hello! {props.name}</h1>    </div>  )}

Presentational components 只從 props 擷取資料和回呼函數,props 由容器組件提供。

容器組件和展示組件各自將資料/邏輯和展示部分封裝到各自的組件中:

const GreetingCard = (props) => {  return (    <div>      <h1>{props.name}</h1>    </div>  )}class Greeting extends React.Component {  constructor() {    super();    this.state = {      name: "",    };  }  componentDidMount() {    // AJAX    this.setState(() => {      return {        name: "William",      };    });  }  render() {    return (      <div>       <GreetingCard name={this.state.name} />      </div>    );  }}

高階組件(Higher order components【HOC’s】)

高階組件是一個接收一個組件作為參數然後返回全新組件的函數。

這是一種強大的模式,我們可以對輸入組件的 props 進行修改(增刪改查)然後返回全新的修改後的組件,例如 react-router-v4 的 withRouter() 方法可以封裝任何自訂群組件,將 react-router 的 history,location,match 三個對象傳入,不需要一級級傳入。例如 Redux,你可以使用 connect({})() 方法來將展示組件和 store 中的資料進行串連。

代碼示範:

import {withRouter} from 'react-router-dom';class App extends React.Component {  constructor() {    super();    this.state = {path: ''}  }    componentDidMount() {    let pathName = this.props.location.pathname;    this.setState(() => {      return {        path: pathName,      }    })  }    render() {    return (      <div>        <h1>Hi! I'm being rendered at: {this.state.path}</h1>      </div>    )  }}export default withRouter(App);

匯出組件時,我使用 react-router-v4 的 withRouter() 來封裝它。在 componentDidMount 這個生命週期中,我們使用 this.props.location.pathname 來更新我們的 state,由於我們使用了 withRouter 高階組件,我們可以直接存取 this.props.locationlocation,而不需要直接將 location 作為 props 直接傳入,非常方便。

Render callbacks

與高階組件類似,render callbacks 或 render props 可以用來重用邏輯。

class Counter extends React.Component {  constructor(props) {    super(props);    this.state = {      count: 0,    };  }  increment = () => {    this.setState(prevState => {      return {        count: prevState.count + 1,      };    });  };  render() {    return (      <div onClick={this.increment}>{this.props.children(this.state)}</div>    );  }}class App extends React.Component {  render() {    return (      <Counter>        {state => (          <div>            <h1>The count is: {state.count}</h1>          </div>        )}      </Counter>    );  }}

在 Counter 類中,我們 render 中嵌入 this.props.childrn 並將 this.state 作為參數。在 App 類下面,我們可以將我們組件封裝在 Counter 組件中。

Counter 組件的本質是暴露了 children 這個外部屬性,將 children 具體的渲染細節交個 Counter 的使用者,使用的時候只需要將組件傳入到 Counter 的 children 中,當然可以使用其他參數,如果 children 不夠的話。例如實現一個聊天列表每條訊息有頭像和訊息內容,具體頭像是圓是方,具體訊息內容是文字是圖片,都交給了外部使用者。

原文:React component patterns

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.