鍍金池/ 教程/ HTML/ 在 React 應(yīng)用中使用 Redux
React 組件
Redux 的基礎(chǔ)概念
JSX
DOM 操作
在 React 應(yīng)用中使用 Redux
進(jìn)化 Flux
Webpack 配置 React 開發(fā)環(huán)境
服務(wù)器端渲染
組合組件
表單
屬性擴(kuò)散
開發(fā)環(huán)境配置
組件生命周期
Data Flow
JSX 與 HTML 的差異
組件間通信
使用 JSX
事件處理
Flux
React 概覽
Mixins
Redux

在 React 應(yīng)用中使用 Redux

和 Flux 類似,Redux 也是需要注冊(cè)一個(gè)回調(diào)函數(shù) store.subscribe(listener) 來獲取 State 的更新,然后我們要在 listener 里面調(diào)用 setState() 來更新 React 組件。

Redux 官方提供了 react-redux 來簡化 React 和 Redux 之間的綁定,不再需要像 Flux 那樣手動(dòng)注冊(cè)/解綁回調(diào)函數(shù)。

接下來看一下是怎么做到的,react-redux 只有兩個(gè) API

<Provider>

<Provider> 作為一個(gè)容器組件,用來接受 Store,并且讓 Store 對(duì)子組件可用,用法如下:

import { render } from 'react-dom';
import { Provider } from 'react-redux';
import App from './app';

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

這時(shí)候 <Provider> 里面的子組件 <App /> 才可以使用 connect 方法關(guān)聯(lián) store。

<Provider> 的實(shí)現(xiàn)很簡單,他利用了 React 一個(gè)(暫時(shí))隱藏的特性 Contexts,Context 用來傳遞一些父容器的屬性對(duì)所有子孫組件可見,在某些場(chǎng)景下面避免了用 props 傳遞多層組件的繁瑣,要想更詳細(xì)了解 Contexts 可以參考這篇文章

Connect

connect() 這個(gè)方法略微復(fù)雜一點(diǎn),主要是因?yàn)樗挠梅ǚ浅l`活:connect([mapStateToProps], mapDispatchToProps], [mergeProps], [options]),它最多接受4個(gè)參數(shù),都是可選的,并且這個(gè)方法調(diào)用會(huì)返回另一個(gè)函數(shù),這個(gè)返回的函數(shù)來接受一個(gè)組件類作為參數(shù),最后才返回一個(gè)和 Redux store 關(guān)聯(lián)起來的新組件,類似這樣:

class App extends Component { ... }

export default connect()(App);

這樣就可以在 App 這個(gè)組件里面通過 props 拿到 Store 的 dispatch 方法,但是注意現(xiàn)在的 App 沒有監(jiān)聽 Store 的狀態(tài)更改,如果要監(jiān)聽 Store 的狀態(tài)更改,必須要指定 mapStateToProps 參數(shù)。

先來看它的參數(shù):

  • [mapStateToProps(state, [ownProps]): stateProps]: 第一個(gè)可選參數(shù)是一個(gè)函數(shù),只有指定了這個(gè)參數(shù),這個(gè)關(guān)聯(lián)(connected)組件才會(huì)監(jiān)聽 Redux Store 的更新,每次更新都會(huì)調(diào)用 mapStateToProps 這個(gè)函數(shù),返回一個(gè)字面量對(duì)象將會(huì)合并到組件的 props 屬性。 ownProps 是可選的第二個(gè)參數(shù),它是傳遞給組件的 props,當(dāng)組件獲取到新的 props 時(shí),ownProps 都會(huì)拿到這個(gè)值并且執(zhí)行 mapStateToProps 這個(gè)函數(shù)。
  • [mapDispatchProps(dispatch, [ownProps]): dispatchProps]: 這個(gè)函數(shù)用來指定如何傳遞 dispatch 給組件,在這個(gè)函數(shù)里面直接 dispatch action creator,返回一個(gè)字面量對(duì)象將會(huì)合并到組件的 props 屬性,這樣關(guān)聯(lián)組件可以直接通過 props 調(diào)用到 action, Redux 提供了一個(gè) bindActionCreators() 輔助函數(shù)來簡化這種寫法。 如果省略這個(gè)參數(shù),默認(rèn)直接把 dispatch 作為 props 傳入。ownProps 作用同上。

剩下的兩個(gè)參數(shù)比較少用到,更詳細(xì)的說明參看官方文檔,其中提供了很多簡單清晰的用法示例來說明這些參數(shù)。

一個(gè)具體一點(diǎn)的例子

Redux 創(chuàng)建 Store,Action,Reducer 這部分就省略了,這里只看 react-redux 的部分。

import React, { Component } from 'react';
import someActionCreator from './actions/someAction';
import * as actionCreators from './actions/otherAction';

function mapStateToProps(state) {
  return {
    propName: state.propName
  };
}

function mapDispatchProps(dispatch) {
  return {
    someAction: (arg) => dispatch(someActionCreator(arg)),
    otherActions: bindActionCreators(actionCreators, dispatch)
  };
}

class App extends Component {
  render() {
    // `mapStateToProps` 和 `mapDispatchProps` 返回的字段都是 `props`
    const { propName, someAction, otherActions } = this.props;
    return (
      <div onClick={someAction.bind(this, 'arg')}>
        {propName}
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchProps)(App);

如前所述,這個(gè) connected 的組件必須放到 <Provider> 的容器里面,當(dāng) State 更改的時(shí)候就會(huì)自動(dòng)調(diào)用 mapStateToPropsmapDispatchProps 從而更新組件的 props。 組件內(nèi)部也可以通過 props 調(diào)用到 action,如果沒有省略了 mapDispatchProps,組件要觸發(fā) action 就必須手動(dòng) dispatch,類似這樣:this.props.dispatch(someActionCreator('arg'))。

下一篇:Flux