react-redux中多个action和reducer是如何关联的

如题,存在多个action和多个reducer,使用combineReducers()合并多个reducer后,怎么知道store派发的action是由哪个reducer处理,根据什么进行判定的?

阅读 9.4k
2 个回答

所有的 reducer 都会收到 action。
reducer 通过 action.type 来进行判定处理。
如果某个 reducer 不处理某个动作,也就是没有处理这个 action.type 的 case, 就会走 default 分支,把 state 原样返回。

目录结构

|-src
|----actions
|--------user.js
|--------office.js
|--------index.js
|----reducers
|--------user.js
|--------office.js
|--------index.js
|----pages
|--------office.js

Action整合

actions目录中的index.js作为所有业务的集合,集中配置管理.

actions/index.js
import * as officeActions from './office';
import * as userActions from './user';

export default {
    ...officeActions,
    ...userActions,
}
actions/office.js
//这里的方法名称要全局唯一
export function getOfficeList(){
    return async(dispatch,getState) => {
        let response = await fetch(url);
        //这里的type一定要全局唯一,因为状态变一次每个Reducer都会根据类型比对一遍
        dispatch({type: 'GET_OFFICE_LIST', payLoad: response.json});
    }
}
export function getOfficeInfo(id){
    return async(dispatch,getState) => {
        let response = await fetch(url+'?id='+id);
        //这里的type一定要全局唯一,因为状态变一次每个Reducer都会根据类型比对一遍
        dispatch({type: 'GET_OFFICE_DETAIL', payLoad: response.json});
    }
}
actions/user.js
//这里的方法名称要全局唯一
export function getUserList(){
    return async(dispatch,getState) => {
        let response = await fetch(url);
        //这里的type一定要全局唯一,因为状态变一次每个Reducer都会根据类型比对一遍
        dispatch({type: 'GET_USER_LIST', payLoad: response.json});
    }
}

Reducer整合

Reducer目录中的index.js 所有子状态的集合,集中配置管理.

reducers/index.js
import {combineReducers} from 'redux';

import officeReducer from './office';
import userReducer from './user';

const appReducer = combineReducers({
    office: officeReducer,
    user: userReducer,
});
export default appReducer;
reducers/office.js
//初始化状态
let initialState = {
    officeList: [],
    officeInfo: {
        "id": "",
        "parent_id": "",
        "parent_ids": "",
        "name": "",
    },
};
const office = (state = initialState, action) => {
    switch (action.type) {
        //处理 类型为 GET_OFFICE_LIST 结果数据
        case 'GET_OFFICE_LIST':
            return Object.assign({}, state, {
                officeList: action.payLoad.data
            });
        //处理 类型为 GET_OFFICE_DETAIL 结果数据
        case 'GET_OFFICE_DETAIL':
            return Object.assign({}, state, {
                officeInfo: action.payLoad.data
            });
        default:
        //如果类型为匹配到 返回当前state
            return state;
    }
};
export default office

最终使用

pages/office.js
import React, {Component} from 'react'
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

//以antd为例
import {Table, Tree, Row, Col, Card, Button, Spin, Modal,Icon} from 'antd';
//引入Action集合,因为很有可能某个页面 需要调用多个子action
import Actions from '../actions';

class office extends Component {
    //生命周期此次不讨论
    componentDidMount() {
        //请求机构 数据
        this.props.action.getOfficeList();
  }

    handleOnRowClick = (officeId)=>{
        //点击行 获取结构详情数据
        this.props.action.getOfficeInfo(officeId);
    }
    
    render() {
        <div className="tableDistance">
        <Table rowSelection={rowSelection} columns={columns}
               dataSource={this.props.office.officeList}//绑定机构数据并展现
               bordered size="middle"
               pagination={false} onRowClick={this.handleOnRowClick}
        />
    </div>
    }

}
//我习惯叫订阅-订阅Reducer/index.js集合中的需要的状态,reducer/office在这里进行绑定(数据结构具体见:initState),reducer/office数据变化这里就会变化,这里可以理解为数据源
const mapStateToProps = (state) => {
    return {
        office: state.office,
        user:state.user
    }
};
//将引入的Actions绑定,使当前展现层具备 请求数据的能力,需要什么数据,就请求对应的 方法名(这就是为什么腔调actions/office.js 中的每个action 名称一定要全局唯一,还是那句话,这个页面可能需要多个子action的数据能力作为数据集中展现的基础)
const mapDispatchToProps = (dispatch) => {
    return {
        action: bindActionCreators(Actions, dispatch)
    }
};
//最重要一步 通过react-redux 提供的 connect函数将 需要的 Reducer和Actions 绑定至 当前页面
export default connect(mapStateToProps, mapDispatchToProps)(office);

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题