redux——入門2

redux——入門1里面,我簡要介紹了redux的核心概念,并舉了一個簡單的計數(shù)器demo的例子,用于展示在react中怎么使用redux?,F(xiàn)在,我打算把這個簡單的demo變得復(fù)雜一點(diǎn),引入react-redux和redux中一些其他的概念。

工具分享

在本篇正式開始之前,我想先分享一個用于快速構(gòu)建react應(yīng)用的腳手架工具,傳送門:https://github.com/facebookincubator/create-react-app

概念引入

我會在這個升級版的demo里面,引入三個東西,Provider(react-redux),combineReducers(redux),connect(react-redux),如果你想更深入的了解react-redux中的各個角色,這里有個很好的解釋https://github.com/jasonslyvia/a-cartoon-intro-to-redux-cn

Provider

這是一個組件,沒有其他特殊的作用,但是我們需要將它包裹在整個組件樹的最外層,只有這樣,其內(nèi)部的子孫組件才能使用connect來綁定store。

connect

這是一個函數(shù),由react-redux提供,其返回依然是一個函數(shù),該函數(shù)會處理視圖與store綁定的細(xì)節(jié),具體的使用方法后面會做介紹。

combineReducers

這也是一個函數(shù)。在上一章,我們的reducer是一個單一的函數(shù),在處理類似于計數(shù)器這樣的簡單應(yīng)用時,我們不會看出有什么問題,但是當(dāng)整個系統(tǒng)變得復(fù)雜后,單一的reducer就會變得臃腫不堪,所以我們需要對reducer進(jìn)行分片,每一個reducer用于單獨(dú)處理一部分state,而combineReducers就是將分片的reducer合并為一個整體,這個函數(shù)的實現(xiàn)也比較簡單。

counter升級版

因為參照了react的官方示例,因此整個例子所使用的語法和上個簡化版的例子會有比較大的出入。

入口文件index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reducer from './reducers';
import Root from './components/root';

let store = createStore(reducer);

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

同簡化版本相比,這里我們引入了Provider,并將其包裹在了組件的最外層。

reducers/index.js

import {combineReducers} from 'redux';
import counter from './counter';

const all = combineReducers({
  count: counter
});

export default all;

在這里,我們調(diào)用了combineReducers方法,將counter這個reducer合并到主reducer上,因為計數(shù)器這個demo很簡單,所以我們只將state劃分了一個屬性count,而counter這個reducer和簡化版的沒有什么區(qū)別,姑且還是貼一下代碼

export default (state=0, action) => {

  switch(action.type) {
    case 'INCREMENT': 
      return state + 1;
    case 'DECREMENT': 
      return state - 1;
    default: 
      return state;
  }
}

前面說過,combineReducer的實現(xiàn)其實是蠻簡單的,其實就是返回一個函數(shù),每次處理action的時候,這個函數(shù)會遍歷所有的reducer來處理這個action,然后將所有結(jié)果打包返回,代碼和下面類似

// combineReducers
const combineReducers = ( reducers ) => {
    return ( state = {}, action ) => {
        return Object.keys(reducers).reduce(
            ( nextState, key ) => {
                nextState[key] = reducers[key](
                    state[key],
                    action
                );
                return nextState;
            },
            {}
        );
    };
};

components/root.js

這是我們的根組件

import React from 'react';
import InputBox from '../containers/input-box';
import ShowBox from '../containers/show-box';

export default () => {
  return (
    <div>
      <InputBox></InputBox>
      <ShowBox></ShowBox>
    </div>
  );
};

這個沒什么可以講的,主要看接下來的InputBox和ShowBox

containers/input-box

這是一個純輸入組件

import React from 'react';
import {connect} from 'react-redux';

let InputBox = ({onIncrement, onDecrement}) => {

  return (
    <div>
      <button type="button" onClick={onIncrement}>+++</button>
      <button type="button" onClick={onDecrement}>---</button>
    </div>
  );
};

let mapDispatchToProps = (dispatch) => ({
  onIncrement: () => dispatch({type: 'INCREMENT'}),
  onDecrement: () => dispatch({type: 'DECREMENT'})
});

InputBox = connect(undefined, mapDispatchToProps)(InputBox);

export default InputBox;

在這里我們調(diào)用了react-redux的connect方法,當(dāng)然,如果之前完全沒接觸過connect函數(shù),看這段代碼可能會有點(diǎn)頭疼,可以先移步這里connect的api文檔。我也可以簡單介紹下connect的使用方法,它支持四個參數(shù),我這里只介紹前兩個,后兩個因為我并沒怎么用過,所以暫時不講。
第一個參數(shù)是mapStateToProps(state, [ownProps]),用于選擇性的將state中的屬性注入到組件的props中,我在show-box中使用了這個參數(shù),所以請看后面的代碼。
第二個參數(shù)是mapDispatchToProps(dispatch, [ownProps]),用于將需要觸發(fā)dispatch的方法,注入到組建的props中,在上面的input-box中,我使用了這個參數(shù),將onIncrementonDecrement兩個用于dispatch的方法注入到了InputBox中。

container/show-box

這是一個純展示的組件

import React from 'react';
import {connect} from 'react-redux';

let ShowBox = ({count}) => {
  return (
    <div>
      <p>{count}</p>
    </div>
  );
};

let mapStateToProps = (state) => ({
  count: state.count
});

ShowBox = connect(mapStateToProps)(ShowBox);

export default ShowBox;

唯一需要注意的是用了mapStateToProps

總結(jié)

雖然是說是升級版,但也只是多引入了幾個東西,總體來說還是算簡單,只是概念多了,容易讓人糊涂,我被繞了一個上午,好在現(xiàn)在總算有點(diǎn)清醒了,所以記下這些東西,方便之后的回顧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容