redux——入門2

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

工具分享

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

概念引入

我會(huì)在這個(gè)升級(jí)版的demo里面,引入三個(gè)東西娃惯,Provider(react-redux)跷乐,combineReducers(redux),connect(react-redux)趾浅,如果你想更深入的了解react-redux中的各個(gè)角色愕提,這里有個(gè)很好的解釋https://github.com/jasonslyvia/a-cartoon-intro-to-redux-cn

Provider

這是一個(gè)組件,沒(méi)有其他特殊的作用皿哨,但是我們需要將它包裹在整個(gè)組件樹(shù)的最外層浅侨,只有這樣,其內(nèi)部的子孫組件才能使用connect來(lái)綁定store证膨。

connect

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

combineReducers

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

counter升級(jí)版

因?yàn)閰⒄樟藃eact的官方示例润梯,因此整個(gè)例子所使用的語(yǔ)法和上個(gè)簡(jiǎn)化版的例子會(huì)有比較大的出入过牙。

入口文件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')
);

同簡(jiǎn)化版本相比甥厦,這里我們引入了Provider,并將其包裹在了組件的最外層寇钉。

reducers/index.js

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

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

export default all;

在這里刀疙,我們調(diào)用了combineReducers方法,將counter這個(gè)reducer合并到主reducer上扫倡,因?yàn)橛?jì)數(shù)器這個(gè)demo很簡(jiǎn)單谦秧,所以我們只將state劃分了一個(gè)屬性count,而counter這個(gè)reducer和簡(jiǎn)化版的沒(méi)有什么區(qū)別撵溃,姑且還是貼一下代碼

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

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

前面說(shuō)過(guò)疚鲤,combineReducer的實(shí)現(xiàn)其實(shí)是蠻簡(jiǎn)單的,其實(shí)就是返回一個(gè)函數(shù)缘挑,每次處理action的時(shí)候集歇,這個(gè)函數(shù)會(huì)遍歷所有的reducer來(lái)處理這個(gè)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>
  );
};

這個(gè)沒(méi)什么可以講的诲宇,主要看接下來(lái)的InputBox和ShowBox

containers/input-box

這是一個(gè)純輸入組件

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)然惶翻,如果之前完全沒(méi)接觸過(guò)connect函數(shù)姑蓝,看這段代碼可能會(huì)有點(diǎn)頭疼,可以先移步這里connect的api文檔吕粗。我也可以簡(jiǎn)單介紹下connect的使用方法纺荧,它支持四個(gè)參數(shù),我這里只介紹前兩個(gè)颅筋,后兩個(gè)因?yàn)槲也](méi)怎么用過(guò)宙暇,所以暫時(shí)不講。
第一個(gè)參數(shù)是mapStateToProps(state, [ownProps])垃沦,用于選擇性的將state中的屬性注入到組件的props中客给,我在show-box中使用了這個(gè)參數(shù),所以請(qǐng)看后面的代碼肢簿。
第二個(gè)參數(shù)是mapDispatchToProps(dispatch, [ownProps])靶剑,用于將需要觸發(fā)dispatch的方法蜻拨,注入到組建的props中,在上面的input-box中桩引,我使用了這個(gè)參數(shù)缎讼,將onIncrementonDecrement兩個(gè)用于dispatch的方法注入到了InputBox中。

container/show-box

這是一個(gè)純展示的組件

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é)

雖然是說(shuō)是升級(jí)版坑匠,但也只是多引入了幾個(gè)東西血崭,總體來(lái)說(shuō)還是算簡(jiǎn)單,只是概念多了厘灼,容易讓人糊涂夹纫,我被繞了一個(gè)上午,好在現(xiàn)在總算有點(diǎn)清醒了设凹,所以記下這些東西舰讹,方便之后的回顧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闪朱,一起剝皮案震驚了整個(gè)濱河市月匣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奋姿,老刑警劉巖锄开,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異称诗,居然都是意外死亡萍悴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門粪狼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)退腥,“玉大人,你說(shuō)我怎么就攤上這事再榄〗屏酰” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵困鸥,是天一觀的道長(zhǎng)嗅蔬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)疾就,這世上最難降的妖魔是什么澜术? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮猬腰,結(jié)果婚禮上鸟废,老公的妹妹穿的比我還像新娘。我一直安慰自己姑荷,他們只是感情好盒延,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布缩擂。 她就那樣靜靜地躺著,像睡著了一般添寺。 火紅的嫁衣襯著肌膚如雪胯盯。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天计露,我揣著相機(jī)與錄音博脑,去河邊找鬼。 笑死票罐,一個(gè)胖子當(dāng)著我的面吹牛叉趣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胶坠,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼君账,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了沈善?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤椭蹄,失蹤者是張志新(化名)和其女友劉穎闻牡,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绳矩,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罩润,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翼馆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片割以。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖应媚,靈堂內(nèi)的尸體忽然破棺而出严沥,到底是詐尸還是另有隱情,我是刑警寧澤中姜,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布消玄,位于F島的核電站,受9級(jí)特大地震影響丢胚,放射性物質(zhì)發(fā)生泄漏翩瓜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一携龟、第九天 我趴在偏房一處隱蔽的房頂上張望兔跌。 院中可真熱鬧,春花似錦峡蟋、人聲如沸坟桅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)桦卒。三九已至立美,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間方灾,已是汗流浹背建蹄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裕偿,地道東北人洞慎。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嘿棘,于是被迫代替她去往敵國(guó)和親劲腿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容