前言
在前面的一文理解Redux中,已經(jīng)知道了Redux的工作流程以及Redux的設(shè)計(jì)基本原則,它就是一個(gè)用于管理組件的公共數(shù)據(jù)狀態(tài)的數(shù)據(jù)層框架,包括了Store,Reducer,React Component,Actions Creators四個(gè)部分
其中核心是Store,他們彼此之間的關(guān)系對(duì)于寫Redux是非常重要的,宏觀上講:也可以將Redux=reducer+Flux的組合,代碼就是文字描述的最佳的體現(xiàn),解釋
你將在本文學(xué)習(xí)到
編寫Redux的的基本流程
如何獲取store中公共的數(shù)據(jù),并展示到頁面上
如何更改store的公共數(shù)據(jù),實(shí)現(xiàn)組件的數(shù)據(jù)與store的同步更新
....更多的細(xì)節(jié)見下文
下面就一起來編寫Redux代碼的,以下是最終實(shí)現(xiàn)的效果圖,添加,刪除列表操作
使用Ant-design布局todolist
對(duì)于初學(xué)者,一個(gè)簡(jiǎn)單的todolist例子對(duì)于入門redux是一個(gè)非常好的實(shí)踐,這就好比剛寫程序時(shí)的Hello-world的,雖然麻雀雖小,但是五脹俱全
在React中要使用Redux時(shí),必須先要在命令行終端下進(jìn)行安裝
- 使用npm或者cnpm,yarn(使用它時(shí),需要先安裝它,然后才可以使用)進(jìn)行安裝
yarn add redux
或者
npm install --save redux
安裝完后,可以在根目錄下package.json查看到redux,如果對(duì)應(yīng)有,說明已經(jīng)安裝成功了的
- ant-design的使用可以參考官方文檔https://ant.design/docs/react/introduce-cn
- 同樣也是需要先安裝,然后在項(xiàng)目中使用
yarn add antd
然后在index.js中引入樣式
import 'antd/dist/antd.css'
當(dāng)然你也可以按需加載組件的方式,具體配置可以參照官方文檔
以下是index.js代碼
import React from 'react';
import ReactDOM from 'react-dom';
import { Input, Button, List } from 'antd'; // 引入antd組件庫
import 'antd/dist/antd.css'; // 引入antd樣式
// TodoList組件
class TodoList extends React.Component {
constructor(props){
super(props);
// 組件內(nèi)部的初始化狀態(tài)數(shù)據(jù)
this.state = {
inputValue: 'itclanCoder', // input表單初始值
list: ['itclanCoder', '川川', '學(xué)習(xí)Redux'] // 下方列表展示的數(shù)據(jù)
}
}
render() {
return (
<div style={{ margin: "10px 0 0 10px"}}>
<div>
<Input value={this.state.inputValue} style={{ width:"300px",marginRight:"10px"}} placeholder="請(qǐng)輸入內(nèi)容..." />
<Button type="primary">提交</Button>
</div>
<List
style={{ width: '300px',marginTop:'10px'}}
bordered
dataSource={this.state.list}
renderItem={item => <List.Item>{item}</List.Item>}/>
</div>
)
}
}
const container = document.getElementById('root');
ReactDOM.render(<TodoList />, container);
最終渲染的UI效果如下所示:
在控制臺(tái)中可以多查看組件state的各個(gè)狀態(tài)的,有助于理解React的
在上面的代碼中,我們發(fā)現(xiàn)組件內(nèi)部的狀態(tài)數(shù)據(jù)是放在當(dāng)前組件的state進(jìn)行存儲(chǔ)管理的,對(duì)于這種小的demo例子,殺雞焉用宰牛刀使用Redux未免有些大才小用,但是如果組件非常的業(yè)務(wù)邏輯非常復(fù)雜,狀態(tài)特別多,那么使用Redux的優(yōu)點(diǎn)就非常明顯了的
下面引入redux,同樣能夠達(dá)到同樣的效果
import React from 'react';
import ReactDOM from 'react-dom';
import { Input, Button, List } from 'antd'; // 引入antd組件庫
import 'antd/dist/antd.css'; // 引入antd樣式
// 1. 創(chuàng)建一個(gè)store管理倉庫,從redux庫中引入一個(gè)createStore函數(shù)
import { createStore } from 'redux';
// 2. 引入createStore后,store并沒有創(chuàng)建,需要調(diào)用createStore()后才有store
const store = createStore(reducer); // 創(chuàng)建好reducer后,需要將reducer作為參數(shù)傳到createStore當(dāng)中去,這樣store才能拿到reducer的state數(shù)據(jù)
// 3. 創(chuàng)建reducer函數(shù),管理組件共享的數(shù)據(jù)狀態(tài)以及一些動(dòng)作
// reducer是一個(gè)純函數(shù),返回一個(gè)新的state給store
// 4. 初始化state值,將原先組件內(nèi)部的狀態(tài)的數(shù)據(jù),移除到reducer里面去管理
function reducer(state = {
inputValue: 'itclanCoder',
list: ['itclanCoder', '川川', '學(xué)習(xí)Redux']
}, action){
return state;
}
// TodoList組件
class TodoList extends React.Component {
constructor(props){
super(props);
// 5. 在組件內(nèi)部通過getState()方法就可以拿到store里面的數(shù)據(jù),該方法能夠獲取到store上存儲(chǔ)的所有狀態(tài)
this.state = store.getState();
}
render() {
return (
<div style={{ margin: "10px 0 0 10px"}}>
<div>
<Input value={this.state.inputValue} style={{ width:"300px",marginRight:"10px"}} placeholder="請(qǐng)輸入內(nèi)容..." />
<Button type="primary">提交</Button>
</div>
<List
style={{ width: '300px',marginTop:'10px'}}
bordered
dataSource={this.state.list}
renderItem={item => <List.Item>{item}</List.Item>}/>
</div>
)
}
}
const container = document.getElementById('root');
ReactDOM.render(<TodoList />, container);
上面的實(shí)例代碼中,完成了將原先定義在組件內(nèi)部的狀態(tài)數(shù)據(jù)抽離到Redux中的reducer去管理,在當(dāng)前組件內(nèi)部通過getState()方法拿到state數(shù)據(jù),最終渲染到頁面上
梳理一下Redux的使用流程:
- 命令行終端下安裝redux第三方庫
yarn add redux
- 在項(xiàng)目中引入redux庫,同時(shí)創(chuàng)建一個(gè)store倉庫,這是通過調(diào)用createStore函數(shù)實(shí)現(xiàn)的
import { createStore } from 'redux';
const store = createStore(); // 調(diào)用createStore函數(shù)才會(huì)真正的創(chuàng)建一個(gè)store
- 創(chuàng)建reducer函數(shù),用于存儲(chǔ)公共組件的數(shù)據(jù)狀態(tài),它是一個(gè)純函數(shù),用于返回組件的狀態(tài)
/*
reducer是一個(gè)純函數(shù),接收兩個(gè)參數(shù),state和action其中state存儲(chǔ)的就是組件的公共狀態(tài)的,而action就是組件派發(fā)的動(dòng)作,reducer的最終結(jié)果是由state和action共同決定的,后面會(huì)接著講action
*/
function reducer(state, action){
return state
}
- 在reducer創(chuàng)建好之后,需要把reducer傳遞給createStore函數(shù)當(dāng)中去,這樣store就拿到了reducer里面的數(shù)據(jù),這一步是必須要做的,否則就會(huì)拿不到reducer中state的數(shù)據(jù)
const store = createStore(reducer);
- 組件內(nèi)如何獲取store中數(shù)據(jù),通過調(diào)用getState方法獲取store中的數(shù)據(jù),該方法能夠獲取到store上存儲(chǔ)的所有狀態(tài)
this.state = store.getState();
- 組件的渲染
<Input value={ this,sate,inputValue }>
<List dataSource={this.state.list} />
上面的過程:其實(shí)完成的就是Redux工作流中的右邊的內(nèi)容
整個(gè)過程總結(jié)一句話就是:引入redux庫,并調(diào)用createStore函數(shù),從而創(chuàng)建了store,緊接著創(chuàng)建reducer函數(shù),用于管理組件公共的狀態(tài)數(shù)據(jù),返回組件公共數(shù)據(jù)的最新的狀態(tài)給store,然后將創(chuàng)建的reducer函數(shù)作為參數(shù),讓createStore函數(shù)接收.
進(jìn)而store就獲取到了reducer函數(shù)里面的公共存儲(chǔ)數(shù)據(jù),當(dāng)組件外部想要拿store的公共數(shù)據(jù)時(shí),于是引入store,并通過getState這個(gè)函數(shù)就可以獲取store中的數(shù)據(jù),最終可將數(shù)據(jù)渲染到頁面上
總結(jié)
本文并不是什么高大上的內(nèi)容,主要是對(duì)學(xué)習(xí)Redux的一個(gè)小小的初探
用幾句簡(jiǎn)單歸納下:組件如何獲取store中的數(shù)據(jù)
安裝redux,然后從redux中引入createStore這個(gè)方法,并調(diào)用它,從而創(chuàng)建store,
緊著在創(chuàng)建reducer純函數(shù),在reducer里面進(jìn)行state的邏輯操作,reducer的返回值取決于state與action這個(gè)的決定,最終該函數(shù)返回最新結(jié)果會(huì)返回給store,完成新舊數(shù)據(jù)的替換,
而在組件中如何獲取store的數(shù)據(jù),是通過getState方法進(jìn)行獲取store中的所有狀態(tài)
那么如何保持頁面的組件與store數(shù)據(jù)同步更新?添加,刪除列表怎么實(shí)現(xiàn)呢?
將在下一節(jié)當(dāng)中揭示了