Redux

在沒有引入Redux之前,對(duì)于各個(gè)組件之間共享狀態(tài)的處理拆吆,通常是用傳給子組件的事件處理器來(lái)處理肛鹏。狀態(tài)的處理分散到各個(gè)組件代碼中逸邦,很不利于維護(hù)。
引入Redux之后在扰,狀態(tài)的管理集中到一個(gè)地方處理缕减,并且把處理過(guò)程中的不同關(guān)注點(diǎn)對(duì)應(yīng)到Action、Reducer芒珠、Store等幾個(gè)概念桥狡。Action:代表要執(zhí)行的動(dòng)作,Reducer:計(jì)算出新的狀態(tài)皱卓,Store:集中應(yīng)用所有的狀態(tài)裹芝。
能夠集中管理狀態(tài),然后分離關(guān)注點(diǎn)娜汁,從而提高代碼可讀性局雄、可維護(hù)性是使用Redux管理狀態(tài)的好處。

Redux適用場(chǎng)景

多交互存炮、多數(shù)據(jù)源

需要共享某個(gè)組件的狀態(tài)

某個(gè)狀態(tài)需要在任何地方都可以拿到

一個(gè)組件需要改變?nèi)譅顟B(tài)

一個(gè)組件需要改變另一個(gè)組件的狀態(tài)

redux方法

import {
    compose,
    createStore,
    applyMiddleware,
    combineReducers,
    bindActionCreator
} from 'redux';

Action

代表發(fā)生了什么事炬搭。

action.js

ActionTypes

ActionCreator

action.js

export const SET_AAA;
export const SET_BBB;
// ...other action constants

export function setAAA(aaa) {
        return {
        type: SET_AAA,
        aaa: aaa
    };
}

export function setBBB(bbb) {
    return {
        type: SET_BBB,
        bbb: bbb
    };
}

// ...other actions

Reducer

表示狀態(tài)如何改變,輸出有最新狀態(tài)穆桂。

注意:只有狀態(tài)的計(jì)算宫盔;不應(yīng)該有副作用;沒有API調(diào)用享完;沒有對(duì)原State的改動(dòng)灼芭。

reducer.js

const initialState = {
    aaa: '',
    bbb: null,
    ccc: null,
    // ...
};

export default function(state = initialState, action) {
    switch(action.type) {
        case "SET_AXXX":
            return {...state, aaa: {...xxx}};
        case "SEND_XXX":
            return {...state, bbb: action.xxx};
        case "SET_BXXX":
            return {...state, bbb: action.bbb};
        case "SET_CXXX":
            return {...state, ccc: action.ccc};
        default:
            return state;
    }
}

Store

一個(gè)應(yīng)用只有一個(gè)Store。
store.js

import { createStore } from 'redux';
import { SomeComponent } from './reducers';

let store= createStore(SomeComponent);


store的提供的方法有:

常用redux插件:react-redux般又,redux-thunk彼绷,redux-logger

react-redux

import {
    connect,
    Provider,
    connectAdvanced,
    createProvider // 最新代碼為:ReactReduxContext -- Nov 7, 2018
} from 'react-redux';

Example

Vanilla React

ReactDOM.render(
  <Provider store={store}>
    <MyRootComponent />
  </Provider>,
  rootEl
)

React Router

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <Route path="/" component={App}>
        <Route path="foo" component={Foo}/>
        <Route path="bar" component={Bar}/>
      </Route>
    </Router>
  </Provider>,
  document.getElementById('root')
)

connect

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

顯示組件(Presentational Components)、容器組件(containers)

State 范式化(摘自官方文檔)

當(dāng)一個(gè)系統(tǒng)較復(fù)雜時(shí)茴迁,有時(shí)數(shù)據(jù)結(jié)構(gòu)會(huì)比較復(fù)雜寄悯,并且有時(shí)部分?jǐn)?shù)據(jù)可能重復(fù)的,有時(shí)還有一些問(wèn)題:

  • 當(dāng)數(shù)據(jù)在多處冗余后堕义,需要更新時(shí)猜旬,很難保證所有的數(shù)據(jù)都進(jìn)行更新。
  • 嵌套的數(shù)據(jù)意味著 reducer 邏輯嵌套更多、復(fù)雜度更高洒擦。尤其是在打算更新深層嵌套數(shù)據(jù)時(shí)椿争。
  • 不可變的數(shù)據(jù)在更新時(shí)需要狀態(tài)樹的祖先數(shù)據(jù)進(jìn)行復(fù)制和更新,并且新的對(duì)象引用會(huì)導(dǎo)致與之 connect 的所有 UI 組件都重復(fù) render熟嫩。盡管要顯示的數(shù)據(jù)沒有發(fā)生任何改變秦踪,對(duì)深層嵌套的數(shù)據(jù)對(duì)象進(jìn)行更新也會(huì)強(qiáng)制完全無(wú)關(guān)的 UI 組件重復(fù) render

正因?yàn)槿绱耍?Redux Store 中管理關(guān)系數(shù)據(jù)或嵌套數(shù)據(jù)的推薦做法是將這一部分視為數(shù)據(jù)庫(kù)掸茅,并且將數(shù)據(jù)按范式化存儲(chǔ)洋侨。

設(shè)計(jì)范式化的 State

范式化的數(shù)據(jù)包含下面幾個(gè)概念:

  • 任何類型的數(shù)據(jù)在 state 中都有自己的 “表”。
  • 任何 “數(shù)據(jù)表” 應(yīng)將各個(gè)項(xiàng)目存儲(chǔ)在對(duì)象中倦蚪,其中每個(gè)項(xiàng)目的 ID 作為 key希坚,項(xiàng)目本身作為 value。
  • 任何對(duì)單個(gè)項(xiàng)目的引用都應(yīng)該根據(jù)存儲(chǔ)項(xiàng)目的 ID 來(lái)完成陵且。
  • ID 數(shù)組應(yīng)該用于排序裁僧。

嵌套數(shù)據(jù)范式化

因?yàn)?API 經(jīng)常以嵌套的形式發(fā)送返回?cái)?shù)據(jù),所以該數(shù)據(jù)需要在引入狀態(tài)樹之前轉(zhuǎn)化為規(guī)范化形態(tài)慕购。Normalizr庫(kù)可以幫助你實(shí)現(xiàn)這個(gè)聊疲。你可以定義 schema 的類型和關(guān)系,將 schema 和響應(yīng)數(shù)據(jù)提供給 Normalizr沪悲,他會(huì)輸出響應(yīng)數(shù)據(jù)的范式化變換获洲。輸出可以放在 action 中,用于 store 的更新殿如。

1. State 范式化
2. 管理范式化數(shù)據(jù)


參考文章:
Redux官方網(wǎng)站
Redux官方文檔中文版
阮一峰 - Redux 入門教程(一):基本用法 共3篇
react-dnd 使用實(shí)例
結(jié)合 Immutable.JS 使用 Redux

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贡珊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涉馁,更是在濱河造成了極大的恐慌门岔,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烤送,死亡現(xiàn)場(chǎng)離奇詭異寒随,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)帮坚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門妻往,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人试和,你說(shuō)我怎么就攤上這事讯泣。” “怎么了灰署?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵判帮,是天一觀的道長(zhǎng)局嘁。 經(jīng)常有香客問(wèn)我溉箕,道長(zhǎng)晦墙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任肴茄,我火速辦了婚禮晌畅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寡痰。我一直安慰自己抗楔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布拦坠。 她就那樣靜靜地躺著连躏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贞滨。 梳的紋絲不亂的頭發(fā)上入热,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音晓铆,去河邊找鬼勺良。 笑死,一個(gè)胖子當(dāng)著我的面吹牛骄噪,可吹牛的內(nèi)容都是我干的尚困。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼链蕊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼事甜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起滔韵,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤讳侨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后奏属,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跨跨,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年囱皿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勇婴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘱腥,死狀恐怖耕渴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情齿兔,我是刑警寧澤橱脸,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布础米,位于F島的核電站,受9級(jí)特大地震影響添诉,放射性物質(zhì)發(fā)生泄漏屁桑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一栏赴、第九天 我趴在偏房一處隱蔽的房頂上張望蘑斧。 院中可真熱鬧,春花似錦须眷、人聲如沸竖瘾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捕传。三九已至,卻和暖如春扩劝,著一層夾襖步出監(jiān)牢的瞬間庸论,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工今野, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留葡公,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓条霜,卻偏偏與公主長(zhǎng)得像催什,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宰睡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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