使用React的一些知识点3

57 阅读2分钟

actionType声明为ES6新增加的Symbol数据类型

当配合react使用redux技术栈时,当应用很大,actionType很多时,如果actionType的数据类型String类型,会出现actionType冲突的情况,“冲突”的意思是,多个reducer可以处理同一个action,但并不是说actionreducer必须要一对一的关系,有些情况下,需要多个reducer处理同一个action。举例:AB页面定义各自的reducer如下:

//pageA/reducer.js
//pageB/reducer.js

function setTab(state = {
    tab: ''
}, action) {
    switch(action.type) {
        case 'setTab': {
            return Object.assign({}, state, {tab: action.tab});
        };
        default: 
            return state;
    }
}

上面是应用中一个reducer纯函数,根据不同的actionType执行不同的case。好,现在页面AB各自在自己的目录中创建一个action.js文件,分别定义各自要dispatchactionCreator,如下:

同事A写的A页面,定义了A页面的一个actionCreator如下:

//pageA/action.js

export const setTab = (tab) => ({type: 'setTab', tab});

同事B写的B页面,定义了B页面的一个actionCreator如下:

//pageB/action.js

export const setTab = (tab) => ({type: 'setTab', tab});

A页面dispatch``setTab这个actionCreator时,本意是想要执行pageA/reducer.js中的setTabcase,结果因为actionType相同,pageB/reducer.js中的setTabcase也会执行。 解决方案:

  • 如果actionTypeString类型,那么对于中小型应用,可以使用命名空间的方式来定义actionType,例如:
export const someActionCreator = () => ({type: `${routeName}_setTab`});
  • 但对于大型应用,使用ES6新增的Symbol数据类型来定义actionType是一种比较好的方案,因为Symbol类型的值都是独一无二的。

对于上面的例子,在AB页面目录下创建一个actionTypes.js文件,例如:

//pageA/actionTypes.js

export const SET_TAB = Symbol('SET_TAB');
//pageB/actionTypes.js

export const SET_TAB = Symbol('SET_TAB');

在各自的actions.js文件中使用actionTypes.js文件中定义的actionType:

//pageA/actions.js
//pageB/actions.js

import {SET_TAB} from './actionTypes.js';

export const setTab = (tab) => ({type: SET_TAB, tab});

在各自的reducer.js文件中使用actionTypes.js文件中定义的actionType:

//pageA/reducer.js
//pageB/reducer.js

import {SET_TAB} from './actionTypes.js';

function setTab(state = {
    tab: ''
}, action) {
    switch(action.type) {
        case SET_TAB: {
            return Object.assign({}, state, {tab: action.tab});
        };
        default: 
            return state;
    }
}

以上就是我在实际使用react中的一些小总结。