【學(xué)習(xí)筆記 】React?⑥ Redux工作流

Redux基礎(chǔ)概念

????在了解Redux之前首先思考一個問題:為什么要使用Redux弱贼?
????React是一個輕量級的視圖層框架兜辞,組件之間的通信方式是這樣的:【學(xué)習(xí)筆記 】React ② 組件拆分以及組件間通信

  • 父組件通過屬性的形式向子組件傳遞數(shù)據(jù)兑徘,既可以傳遞數(shù)據(jù)又可以傳遞方法贞瞒;子組件通過this.props中接收傳遞過來的方法和數(shù)據(jù)
  • 子組件調(diào)用父組件的方法叼旋,修改父組件的內(nèi)容子組件通過this.props.func()就可以調(diào)用父組件的方法刃麸,父組件傳遞的函數(shù)this指向要做綁定阎抒,借助這個方法對父組件的數(shù)據(jù)進行修改
store.png

????當我們在實現(xiàn)一些簡單項目的時候酪我,是沒有任何問題的。但是如果開發(fā)發(fā)型復(fù)雜項目且叁,組件之間的通信就會變得復(fù)雜都哭,產(chǎn)生許多不利維護的代碼。上面的圖可以形象的表現(xiàn)出引入Redux的優(yōu)勢逞带,把數(shù)據(jù)放在store進行管理欺矫,一個組件改變了store里面的數(shù)據(jù),其他組件就會感知到這個變化展氓,從而進行渲染穆趴。

Redux工作流

????將Redux當作一個圖書管理系統(tǒng),react components看成一個借書的用戶遇汞,action creators看作‘要借什么書’這句話未妹,store看作圖書管理員,reducer看作是圖書管理員的筆記本空入。下圖很形象表示出了這一流程络它。

reduxFlow.png

????components發(fā)出action,通過store.dispatch()告知store歪赢。store則通過與reducer通信化戳,獲取到newState。將新的state傳遞給components埋凯,完成通信点楼。這就是redux的工作流扫尖。依照這個工作流,對Todolist工程進行改造掠廓。

一藏斩、使用Ant Design重新編寫Todolist頁面布局

官方文檔:https://ant.design/docs/react/introduce-cn

  • 安裝Ant Design
yarn add antd
  • Todolist.js中引入樣式文件以及需要的組件
import React, {Fragment, Component} from 'react';
import TodoItem from './TodoItem'
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
import { Input, Button, List } from 'antd';
import store from './store'

class Todolist extends React.Component{
    constructor (props) {
        super(props)
    }
    render() {
        // console.log('render')
        return (
            <Fragment>
                <div>
                    <Input value={this.state.inputValue}
                        placeholder={'to do info'}
                        style={{width: '300px', marginRight: '10px'}}
                    />
                    <Button type="primary">提交</Button>
                </div>
                <List
                    style={{width: '300px', marginTop: '10px'}}
                    bordered
                    dataSource={this.state.list}
                    renderItem={item => (
                        <List.Item>{item}</List.Item>
                    )}
                />
            </Fragment>
        );
    }
}

export default Todolist;

在瀏覽器效果如下:


Todolist新的頁面布局

二、實現(xiàn)Redux Flow

  • 安裝 redux
yarn add redux
  • createStore
    src目錄下新建store文件夾却盘,在該文件夾下新建index.js文件
// 創(chuàng)建store
import { createStore } from 'redux'
const store = createStore();
export default store
  • 創(chuàng)建reducer
    store文件夾下新建reducer.js文件
export default (state , action) => {
    return state
}
  • 將reducer傳遞給createStore
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
// const store = createStore(reducer);
// 增加 window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 是為了使用Reduce DevTools
export default store
  • action 和 reducer 的編寫
    ????以通過實現(xiàn)Todolist基本功能為例來實現(xiàn)actionreducer的編寫∠彼基本功能如下:
    (1)在input文本框中輸入待辦事項
    (2)點擊提交按鈕黄橘,將待辦事情渲染在頁面上,清空文本框內(nèi)容
    (3)點擊某項待辦事項屈溉,可將其刪除
    1.在store中設(shè)置基礎(chǔ)數(shù)據(jù)
const defaultState = {
    inputValue: '',
    list: []
}
export default (state = defaultState, action) => {
    console.log(state, action)
    return state
}

2.在Todolist.js中通過store.getState()獲取store中的數(shù)據(jù)塞关,將inputValue綁定在input文本框,并在文本框綁定onChange()事件

 <Input value={this.state.inputValue}  placeholder={'to do info'}   style={{width: '300px', marginRight: '10px'}}  onChange={this.handleInputChange} />

  handleInputChange(e) {
        const action = {
            type: 'change_input_value', // 描述這個action是干嘛的
            value: e.target.value
        }
        store.dispatch(action)
    }

3.完成storereducer之間的通信

// reducer 可以接收state子巾,但是絕不能修改state
export default (state = defaultState, action) => {
    if (action.type === 'change_input_value') {
        // 深拷貝 state
        const newState = JSON.parse(JSON.stringify(state));
        newState.inputValue = action.value
        return newState
    }
    console.log(state, action)
    return state
}

????以上就實現(xiàn)了第一個基本功能帆赢,store中的值是否隨著input文本框的輸入而改變?我們在瀏覽器中看一下效果线梗,


redux-input.gif

????我們可以看到state中的值確實隨著input文本框中輸入的內(nèi)容發(fā)生改變而改變椰于。后面兩個功能也類似,只需要為ButtonList.Item綁定對應(yīng)的事件仪搔,按照上面流程修改reducer即可瘾婿。

 handleBtnClick () {
        const action = {
            type: 'add_todo_item'
        }
        store.dispatch(action)
 }
handleItemDelete (index) {
         const action = {
             type: 'del_todo_list_item',
             value: index
         }
        store.dispatch(action)
 }
 if (action.type === 'add_todo_item') {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.push(newState.inputValue)
        newState.inputValue = ''
        return newState
    }
    if (action.type === 'del_todo_list_item') {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.splice(action.value, 1)
        return newState
    }

三、actionCreator的統(tǒng)一創(chuàng)建

????以上的代碼雖可以實現(xiàn)ReduxFlow烤咧,但是從可維護性偏陪,以及前端自動化測試方面體驗都不是很好,因此我們需要將actionCreator做統(tǒng)一管理煮嫌。

????在store文件夾下新建actionTypes.jsactionCreators.js笛谦,分別管理typeaction

// actionTypes.js
export const CHANGE_INPUT_VALUE = 'change_input_value'


//actionCreators.js
import { CHANGE_INPUT_VALUE } from './actionTypes'
export const getInputChangeAction = (value) => ({
    type: CHANGE_INPUT_VALUE,
    value
})

// Todolist.js
handleInputChange(e) {
    const action = getInputChangeAction(e.target.value)
    store.dispatch(action)
 }

一些零散的點

  • redux設(shè)計和使用的三項原則
    1.store是唯一的
    2.只有store能改變自己的內(nèi)容
    3.reducer必須是純函數(shù)

  • 核心API
    1.createStore
    2.store.dispatch
    3.store.getState
    4.store.subscribe

項目完整代碼地址:https://github.com/cindygogogo/studyReact

(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昌阿,隨后出現(xiàn)的幾起案子饥脑,更是在濱河造成了極大的恐慌,老刑警劉巖宝泵,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件好啰,死亡現(xiàn)場離奇詭異,居然都是意外死亡儿奶,警方通過查閱死者的電腦和手機框往,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闯捎,“玉大人椰弊,你說我怎么就攤上這事许溅。” “怎么了秉版?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵贤重,是天一觀的道長。 經(jīng)常有香客問我清焕,道長并蝗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任秸妥,我火速辦了婚禮滚停,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粥惧。我一直安慰自己键畴,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布突雪。 她就那樣靜靜地躺著起惕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咏删。 梳的紋絲不亂的頭發(fā)上惹想,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音饵婆,去河邊找鬼勺馆。 笑死,一個胖子當著我的面吹牛侨核,可吹牛的內(nèi)容都是我干的草穆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼搓译,長吁一口氣:“原來是場噩夢啊……” “哼悲柱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起些己,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤豌鸡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后段标,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涯冠,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年逼庞,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛇更。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖派任,靈堂內(nèi)的尸體忽然破棺而出砸逊,到底是詐尸還是另有隱情,我是刑警寧澤掌逛,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布师逸,位于F島的核電站,受9級特大地震影響豆混,放射性物質(zhì)發(fā)生泄漏篓像。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一皿伺、第九天 我趴在偏房一處隱蔽的房頂上張望遗淳。 院中可真熱鬧,春花似錦心傀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至种呐,卻和暖如春宰翅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爽室。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工汁讼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阔墩。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓嘿架,卻偏偏與公主長得像,于是被迫代替她去往敵國和親啸箫。 傳聞我的和親對象是個殘疾皇子耸彪,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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