如何处理useReducer()中的不纯函数

时间:2020-05-20 12:50:24

标签: reactjs react-hooks

我需要在上下文状态下将数据从一个数组传输到另一个数组,因此我选择使用useReducer()。动作就是这样

        case 'ADD_CATEGORY':{
            if(state.catList.length>0){
                let nextState = { ...state }; 
                let catList = state.catList.filter(c => c.localeCompare(state.category)!==0);
                let categories = state.categories;
                categories.push (state.category);

                nextState.categories = categories;
                nextState.catList = catList;
                console.log(state.category);
                return nextState
            }else return state;
        }

状态是这样

    const initialState = {
        towns:[],
        name: '',
        parish: '',
        category: '',
        townsToSubmit: [],
        categories:[],
        catList:[],
    }

根据this github问题,如果我正确读取线程,我应该期望useReducer()调用两次,因为react应用程序使用严格模式,并查看我的代码是否引起副作用。添加到数组时该怎么做。

这引起的主要问题是我的数组最终重复了元素,因为它们总是被添加两次。因为StrictMode应该可以帮助检测副作用,所以它们是向数组添加数据的更好方法吗?

1 个答案:

答案 0 :(得分:1)

随着Redux的创建者不断强调,您的简化器必须是纯正的。 { ...state }创建state浅拷贝,因此,如果您修改状态中任何引用类型的值(例如,通过在数组上使用.push()),该变化将在该状态的先前版本和下一版本中发生。如果由于严格模式而将相同的修改重复两次,则表示您有问题。

因此仅使用纯操作:

 case 'ADD_CATEGORY':{
     if(state.catList.length > 0) {
         return {
            ...state,
            catList: state.catList.filter(c => c.localeCompare(state.category) !== 0),
            categories: [...state.categories, state.category],
         };
      }

      return state;
}