Redux 使用流程與個(gè)人心得(一)

Redux 是React生態(tài)中重要的組成部分狐援。很多人都說(shuō)囊拜,簡(jiǎn)單的應(yīng)用可以不用此工具某筐。但是我個(gè)人認(rèn)為,中小型應(yīng)用使用的話艾疟,可以使文件結(jié)構(gòu)更加規(guī)范来吩,代碼可讀性更強(qiáng)。因?yàn)镽eact提出將展示組件與容器組件分離的思想蔽莱,所以降低了React 與Redux之間的耦合度弟疆。

網(wǎng)上廣為流傳的Redux流向圖,可以幫助我們更好地理解并使用盗冷。
Redux Flux.png

我個(gè)人粗淺的理解是:
Store的角色是整個(gè)應(yīng)用的數(shù)據(jù)存儲(chǔ)中心怠苔,集中大部分頁(yè)面需要的狀態(tài)數(shù)據(jù);
ActionCreators ,view 層與data層的介質(zhì)仪糖;
Reduce 柑司,接收action并更新Store。
所以流程是 用戶通過(guò)界面組件 觸發(fā)ActionCreator锅劝,攜帶Store中的舊State與Action 流向Reducer,Reducer返回新的state攒驰,并更新界面。

所以也可以按照這個(gè)流程思想故爵,來(lái)構(gòu)建代碼的結(jié)構(gòu)了玻粪。


實(shí)現(xiàn)一個(gè)很簡(jiǎn)單的結(jié)構(gòu).png

上圖實(shí)現(xiàn)的就是輸入輸出的東西。輸入框內(nèi)輸入一些內(nèi)容,confirm后劲室,label顯示相應(yīng)內(nèi)容伦仍。

最開始
先安裝幾個(gè)庫(kù)

npm install --save prop-types
npm install --save react-redux
npm install --save redux

1、首先構(gòu)造界面

component/AddName.js

-這是一個(gè)純React代碼 很洋,結(jié)構(gòu)清晰充蓝。

//component/AddName.js
import React, { Component } from 'react';
import PropTypes from 'prop-types'

class AddName extends Component {
  //聲明屬性
  static propTypes = {
    lastname:PropTypes.string.isRequired,
    addNameCreater:PropTypes.func.isRequired,
    lastage:PropTypes.number.isRequired,
    addAgeCreater:PropTypes.func.isRequired,
    addNameAsync:PropTypes.func.isRequired
  }
//點(diǎn)擊事件
  handlerFunc = () =>{
    const inputName = this.refs.inputValueTest.value;
    this.props.addNameCreater(inputName);
  }
  handlerAgeFunc = () =>{
    const inputage = this.refs.inputValueAge.value;
    this.props.addAgeCreater(inputage);
  }
  handlerAsyncFunc = () =>{
    const inputName = this.refs.inputValueTest.value;
    this.props.addNameAsync(inputName);
  }
//渲染界面
  render() {
    const {lastname,lastage} = this.props;   
    return (
      <div>
        <header className="App-header">
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <label> {lastname} </label><br/>
        <input ref="inputValueTest" /><br/>
        <button onClick={this.handlerFunc}>confirm</button><br/>

        <label> {lastage} </label><br/>
        <input ref="inputValueAge" />
        <button onClick={this.handlerAgeFunc}>confirm</button><br/>

        <button onClick={this.handlerAsyncFunc}>Async Confirm</button><br/>
      </div>
    );
  }
}

export default AddName;


2、然后喉磁,根據(jù)流程圖谓苟,我們需要定義一些操作了,也就是ActionCreator.它會(huì)傳達(dá)用戶的操作信息以及一些數(shù)據(jù)

先定義一些常量供我們使用,這里就兩種操作线定,一是添加名字娜谊,二是添加年齡,實(shí)際都一樣斤讥。為了后面實(shí)現(xiàn)reducer的合并強(qiáng)行寫了倆纱皆。這寫常量一般都定義在actionTpye文件中

Redux/actionType.js

export const ADDNAME = 'ADDNAME'
export const ADDAGE = 'ADDAGE'

接著就是寫ActionCreator ,定義了一些操作類型芭商,告訴store自己是干什么的派草,需要什么樣的數(shù)據(jù)。

Redux/actions.js

import { ADDNAME,ADDAGE } from "./action-type";

//包含所有的action creator
export const addNameCreater = (name) =>({type:ADDNAME,data:name})
export const addAgeCreater = (age) => ({type:ADDAGE,data:age})
export const addNameAsync = (name) =>{
    return dispatch =>{
        setTimeout(()=>{
            dispatch(addNameCreater(name))
        },2000);
    }
}

3铛楣、Reducer 會(huì)接收到action的信息近迁。將會(huì)進(jìn)行狀態(tài)(數(shù)據(jù))的處理,相當(dāng)于react中的setState()的功能簸州。如果有多個(gè)reducer 鉴竭,可以使用combineReducers方法將其合并,并暴露出去岸浑。

Redux/reducer.js

//包含n個(gè)reducer函數(shù)的模塊
import {ADDNAME, ADDAGE} from './action-type'
import {combineReducers} from 'redux'
function addName(state='initRedux',action){ //形參默認(rèn)值
    switch(action.type){
        case ADDNAME:
            return action.data
        default:
            return state
    }
}
function addAge(state=0,action){
    switch(action.type){
        case ADDAGE:
            return action.data
        default:
            return state
    }
}

export const finalReducer = combineReducers({
    addName,addAge
})

其中state='initRedux' 搏存、state=0 相當(dāng)于我們?cè)赗eact組件內(nèi)部初始化state.

4、一切操作還是基于Store 的矢洲。類似于中央集權(quán)璧眠。所以還要把Store建立出來(lái)

Redux/store.js

import {createStore,applyMiddleware} from 'redux'
import {finalReducer } from './reducers'
import thunk from 'redux-thunk'
//生成store對(duì)象
const store = createStore(finalReducer,applyMiddleware(thunk));//內(nèi)部會(huì)第一次調(diào)用reducer函數(shù),得到初始state 

export default store

因?yàn)閞educer會(huì)更新Store中的狀態(tài)(數(shù)據(jù))读虏,所以需要引入reducer 责静,并創(chuàng)建store.

到此,流程圖到這里就走完了盖桥。不過(guò)2灾螃、3、4都是redux中負(fù)責(zé)接管React 狀態(tài)的功能揩徊。1是React負(fù)責(zé)展示的組件睦焕。兩者并沒(méi)啥關(guān)系藐握。既然有了展示組件,接下來(lái)就要有容器組件了垃喊。也就是能夠?qū)eact與redux相關(guān)聯(lián)的一個(gè)組件。

5袜炕、構(gòu)建容器組件

containers/App.js

import React from 'react'
import {connect} from 'react-redux'
import {addNameCreater,addAgeCreater,addNameAsync} from '../redux/actions'
import AddName from '../component/AddName'
export default connect(
    state => ({
        lastname:state.addName,
        lastage:state.addAge
    }),
    {addNameCreater,addAgeCreater,addNameAsync}
)(AddName)

這里用到了react- redux中的connect 本谜。可以將React與redux關(guān)聯(lián)起來(lái)偎窘。AddName就是第一步寫的組件名乌助。state中關(guān)聯(lián)了React中的屬性。這里面涉及到兩個(gè)API陌知,到第二章詳細(xì)描述他托。

6、添加store

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'

import App from './containers/App'
import store from './redux/store'

ReactDOM.render((
//使用Provider 組件將APP主組件包裹住仆葡,這樣內(nèi)部組件都有Store種提供的屬性赏参。
    <Provider store={store}>
        <App/>
    </Provider>
), document.getElementById('root'));

這樣就OK了。

文件結(jié)構(gòu).png

上圖是主要的文件結(jié)構(gòu)沿盅,
-redux 集中管理狀態(tài)(數(shù)據(jù))
-component 專注于React 展示組件部分
-containers 集中處理React與redux交互的部分

此外把篓,redux還可以處理一些異步請(qǐng)求。這樣的話腰涧∪脱冢可以做到data 和view 的管理分離,增強(qiáng)了工程結(jié)構(gòu)的可讀性與可維護(hù)性窖铡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疗锐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子费彼,更是在濱河造成了極大的恐慌滑臊,老刑警劉巖匕积,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迅矛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惭墓,警方通過(guò)查閱死者的電腦和手機(jī)虹钮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門聋庵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人芙粱,你說(shuō)我怎么就攤上這事祭玉。” “怎么了春畔?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵脱货,是天一觀的道長(zhǎng)岛都。 經(jīng)常有香客問(wèn)我,道長(zhǎng)振峻,這世上最難降的妖魔是什么臼疫? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮扣孟,結(jié)果婚禮上烫堤,老公的妹妹穿的比我還像新娘。我一直安慰自己凤价,他們只是感情好鸽斟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著利诺,像睡著了一般富蓄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慢逾,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天立倍,我揣著相機(jī)與錄音,去河邊找鬼氛改。 笑死帐萎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胜卤。 我是一名探鬼主播疆导,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼葛躏!你這毒婦竟也來(lái)了澈段?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤舰攒,失蹤者是張志新(化名)和其女友劉穎败富,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摩窃,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兽叮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猾愿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹦聪。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒂秘,靈堂內(nèi)的尸體忽然破棺而出泽本,到底是詐尸還是另有隱情,我是刑警寧澤姻僧,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布规丽,位于F島的核電站蒲牧,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赌莺。R本人自食惡果不足惜冰抢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艘狭。 院中可真熱鬧晒屎,春花似錦、人聲如沸缓升。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)港谊。三九已至,卻和暖如春橙弱,著一層夾襖步出監(jiān)牢的瞬間歧寺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工棘脐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斜筐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓蛀缝,卻偏偏與公主長(zhǎng)得像顷链,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子屈梁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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