一、结构
Redux主要由这几部分构成
1.Container(card.js)
2.Action (cardAction.js)
3.Reducer (cardReducer.js)
4.Saga (cardSaga.js)
这几个文件分别起什么作用不赘述了。
下面我直接进入实例:在前端获取我们账户绑定的银行卡信息。(后台到前端数据传递)
二、Action部分
根据功能要求,我们在cardAction.js中这样写
//cardAction.js
export const SHOW_BANK_CARD_DATA = 'SHOW_BANK_CARD_DATA';
export const SHOW_BANK_CARD_DATA_SUCCESS = 'SHOW_BANK_CARD_DATA_SUCCESS';
export function getShowBankCardData(){
return {type: SHOW_BANK_CARD_DATA}
}
SHOW_BANK_CARD_DATA-------------动作:读取银行卡SHOW_BANK_CARD_DATA_SUCCESS------------动作:银行卡被成功读取
三、Saga部分
cardSaga.js的作用就是监听SHOW_BANK_CARD_DATA,当这个动作发生了,就调服务端的数据。
SHOW_BANK_CARD_DATA在cardSaga.js被调用,
具体实现:
1.我们在cardSaga.js中设置watchGetAllBankCardData()函数来监听SHOW_BANK_CARD_DATA动作。
2.监听到container发来的动作后,我们调用getAllBanks()函数,来访问BankModel.allBanks这个API接口。
3.把从API接口传来的后台数据保存成json文件传递给SHOW_BANK_CARD_DATA_SUCCESS。
//cardSaga.js
function* getAllBanks(){
let json = yield call(BankModel.allBanks);
yield put({
type: actions.SHOW_BANK_CARD_DATA_SUCCESS,
json: json
})
}
export function* watchGetAllBankCardData(){
yield takeEvery(actions.SHOW_BANK_CARD_DATA, getAllBanks)
}
//存API的.js文件
export var BankModel = {
getBankName:(card_id)=>_api("GET", API("/api/v1/bank/searchbank"),{card_id}), // 根据银行卡号,返回银行名
confirmAddBank:(card_id, cardholder, bank_name)=>_api("GET", API("/api/v1/bank/addcard"),{card_id, cardholder, bank_name}), // 添加银行卡
allBanks:()=>_api("GET", API("/api/v1/bank/allbanks")), //获取已绑定的所有银行卡信息
deleteOneInfo: (id)=>_api("GET", API("/api/v1/bank/deleteoneinfo"),{id}), //删除一条银行卡信息
chooseCashoutCard: (id)=>_api("GET", API("/api/v1/bank/choosecashoutcard"),{id})
};
四、By the way
这里有个问题,container怎么发出的SHOW_BANK_CARD_DATA这个动作的呢。
//card.js
class ShowBankCardContainer extends React.Component{
constructor(props){
super(props);
this.props.actions.getShowBankCardData();
}
从代码中我们能看出,组件被构造出来之后我们调用了cardAction.js中传来的函数this.props.actions.getShowBankCardData()来执行SHOW_BANK_CARD_DATA动作。
除了这种方式,我们还能把动作和前端绑起来,比如按下某个按钮,就执行某个动作。例如我们的DELETE_ONE_BANK_CARD动作就是在按下按钮后执行的。
delete(id, index) {
this.props.actions.deleteBankCard(id, index);
}
<button onClick={this.delete.bind(this,item.id, index)}>
五、Reducer部分
我们拿到后台传来的json后,通过cardReducer.js进行处理。
1.我们先初始化allcards这个state对象,并用status,msg,data这三个子state来接收json。这三个state设置的很有讲究:
status为0的时候,说明与后台访问成功(这是后端程序员规定的),返回status和data。
status非0的时候,说明与后台访问失败(这是后端程序员规定的),返回status和msg。
这说明data携带的是json传来的数据,而msg是json传来的访问失败错误信息,status携带的是指示(本例中为0 / 1)。
//cardReducer.js
const initialState = {
allcards: {
status: 1,
msg: '',
data: [], // 所有绑定的银行卡信息
},
export function showBankCardReducer(state=initialState, action){
switch(action.type){
case showBankCardActions.SHOW_BANK_CARD_DATA_SUCCESS:
let allcards_status = action.json.status;
if (allcards_status !== 0){
let allcards = {status: allcards_status,msg:action.json.msg};
return Object.assign({}, state, {allcards})
}else{
let allcards = {status: allcards_status, data: action.json.data};
return Object.assign({}, state, {allcards})
}
default:
return state
}
}
2.我们把allcards和state的值传给了{},而不是把allcards传给state,为了不改变state本身的值。这点体现了reducer作为一个纯函数,每次输出的值不受先前的值影响。
经过reducer处理后,我们在container即card.js中拿到这些state
//cardReducer.js
return Object.assign({}, state, {allcards})
//card.js
function mapStateToProps(state){
const allcards = state.showBankCardReducer.allcards;
return {
allcards
}
}
3.这样我们就能用this.props.allcards.data把allcards的数据传到前端了
//card.js
<p>this.props.allcards.data</p>
结语:麻雀虽小,五脏俱全。本文没涉及store以及Action,Reducer绑定Container,因为那太简单了。