回顧
- 初識react(一) 揭開jsx語法和虛擬DOM面紗
- 初識react(二) 實現一個簡版的html+redux.js的demo
- 初識react(三)在 react中使用redux來實現簡版計數器
- 初識react(四) react中非同步解決方案之 redux-saga
- 初識react(五) 資料流終極解決方案 dva(零配置)
上篇文章已經把redux核心概念講明白了,這裡就不在廢話啦,不瞭解的可以先去回顧下,接下來我們講解下在react中如何使用redux,來實現一個簡單計數器
先把目錄結構搭好
下面我們講解下每個檔案的作用,然後在一個一個實現
- actions->counter.js存放計數器的動作
- reducers->index.js是主入口檔案,因為可能有好多個reducer。
- reducers->counter.js存放計數器的reducer
- action-types.js 存放巨集,玩遊戲的肯定知道,儲存動作的型別
- store->index.js 是整個store對外暴露的入口檔案
讀過上篇文章後,對這種目錄結構可能還不清楚具體的作用,但是對這些redux中概念肯定已經明白,下面我們一個一個檔案開始講解
一、編寫store部分
1、編寫最簡單的store/action-types.js檔案
- 是一個巨集檔案,儲存計數器動作的型別,說白了就是加、減操作。貼程式碼看的更具體
// action-types
export const INCREMENT = "INCREMENT";
export const DECREMENT = "DECREMENT";
複製程式碼
巨集檔案不是必須的,但是它好處是結構清晰,一目瞭然可以看到計數器所有動作的型別
2、編寫reducers/counter.js檔案
- 是一個計數器的reducer,reducers目錄下可能有很多個reducer,我們先寫一個
import * as Types from "../action-types"; //引入動作型別
let initState = { //宣告一個初始的狀態
number:0
};
function counter(state = initState, action) { //接收state和action兩個引數,並給state賦予初始值
switch (action.type) { //判斷動作型別
case Types.INCREMENT: //action類似這種結構{type:'INCREMENT',count:5}
return {number:state.number+action.count};
case Types.DECREMENT:
return {number:state.number-action.count};
}
return state
}
export default counter
複製程式碼
跟我們上篇文章寫的reducer一模一樣,只不過我們把它抽離出來,讓結構清晰
3、編寫reducers/index.js檔案
- 由於我們只有一個計數器的reducer,所以預設匯出就可以。當有多個reducer,會在這個檔案進行合併,後面再講。
import counter from "./counter"; //預設匯入reducer
export default counter //預設匯出
複製程式碼
在囉嗦一句,主要是為了以後方便擴充套件多個reducer,所以才會有reducers/index.js這個主檔案
4、 編寫actions/counters.js
- 把派發的動作抽離出來,用於來元件中呼叫
import * as Types from "../action-types"; //引入巨集
let actions = {
add(num){ //add方法會在元件內部呼叫,返回action物件
return {type:Types.INCREMENT,count:num}
},
minus(num){
return {type:Types.DECREMENT,count:num}
}
};
export default actions
複製程式碼
5、編寫store/index.js,倉庫的主檔案
- 這個檔案主要用於匯出store,提供給元件使用
import {createStore} from 'redux';
import reducer from "./reducers"
let store = createStore(reducer); //建立store
export default store;
複製程式碼
截止到目前為止,store檔案已經全部寫完。下面我們開始寫元件部分,讓倉庫中資料給元件使用
二、元件呼叫部分
1、編寫react的主入口檔案,即 src/index.js
- 使用react-redux庫,來實現store和元件之間的通訊
- react-redux提供了2個核心API, Provider 提供 connect 連結
- Provider是一個元件,在react入口檔案中用於提供store。
- connect含義是,在react元件內部連線store,進而實現元件與redux之間通訊
怪我不能給大家講明白,我們還是看程式碼逐句解釋
import React from 'react';
import ReactDOM from 'react-dom';
import Counter from "./components/Counter";
import store from "./store";
//引入react-redux中的Provider元件,用於
import {Provider} from "react-redux";
ReactDOM.render(
<Provider store = {store}>
<div>
<Counter />
</div>
</Provider>, document.getElementById('root'));
複製程式碼
2、編寫Counter元件
- 元件中用到connect方法,實現元件與redux之間通訊,connect方法接受2引數。connect(mapStateToProps,actions)(Counter)
- 把store/actions.js匯出的物件繫結到元件的屬性中,元件內部可以通過this.props拿到對應的actions
import React from "react";
import store from "../store";
import * as Types from "../store/action-types"
//生成action的物件的方法叫actionCreator
import actions from "../store/actions/counter";
import {connect} from "react-redux";
class Counter extends React.Component {
render() {
console.log(this.props);
return (
<div>
<div>{this.props.number}</div>
<button onClick={()=>{
this.props.add(5)
}}>+</button>
<button onClick={()=>{
this.props.minus(1)
}}>-</button>
</div>
)
}
}
let mapStateToProps = (state)=>{ //state代表的store.getState()
return {...state}
};
export default connect(mapStateToProps,actions)(Counter)
複製程式碼
到此為止,我們基本實現一個計數器功能,先來測試下,然後在梳理下整個工作流程
測試點選增加記數功能
功能基本實現,可能對整個流程並不清楚怎麼實現的,下面來梳理下整個工作流程
react-redux整個流程分析
- 當點選按鈕觸發 this.props.add(5),返回的action即{type:Types.INCREMENT,count:num},會在connect內部被派發
- 派發動作後被reducer處理,然後返回新的狀態
- 頁面重新整理
最後來張圖結尾