在react-redux应用程序中仅修改状态的一部分

时间:2018-09-03 13:16:34

标签: reactjs redux react-redux

作为练习,我正在编写一个react-redux计算器应用程序。我的应用程序的状态定义为:

const initialState = {
  operator1: "",  //first operand
  operator2: "",  //second operand
  currentOp: "",  // +, -, *, /
  display:"",     //the current calculator display
  currentOperator:1  //which operand is being entered right now
}

currentOp包含计算器当前正在执行的操作的符号,当输入第一个操作数时,该符号为空。因此,当按下计算器的数字时,我需要更新显示,但又不要失去其他状态属性。我这样写我的减速器:

import {NUMBER_PRESSED,OPERATION_PRESSED,EQUAL_PRESSED} from './actions';

const mainReducer = (state ={},action) =>
{
console.log("reducer called!");
console.log(action);
const newState = {};

//copy the operators to the new state. Only one will be changed. (Is this really necessary?)
newState.operator1 = state.operator1;
newState.operator2 = state.operator2;

switch(action.type)
{

    case NUMBER_PRESSED:
        if (state.currentOperator===1)
        {
            newState.operator1 = state.operator1 + action.payload;
            newState.display= newState.operator1;
        }
        if(state.currentOperator===2)
        {
            newState.operator2 = state.operator2 + action.payload;
            newState.display= newState.operator2;
        }

        //set the other properties of the state (Is this really necessary?)
        newState.currentOperator = state.currentOperator;
        newState.currentOp = state.currentOp;

        console.log("The new state is:");
        console.log(newState);
        return newState;

    case OPERATION_PRESSED:

        break;
    case EQUAL_PRESSED:

        break;

    default:
        return state;
}
}

export default mainReducer;

请注意,我还没有执行计算操作,只是更新了显示内容。如果直接更改状态变量,则计算器组件不会更新。可以理解,这是文档中解释的预期行为。但是,似乎我需要手动将整个状态复制到一个新变量中,以便保留下一个状态(请注意代码中的“这真的有必要吗?”注释。 我可以复制所有应用程序的状态并返回一个全新的状态对象,但是在具有巨大状态树的大型应用程序中会发生什么呢?如何管理?有没有办法在Redux中仅修改部分状态?

2 个答案:

答案 0 :(得分:0)

您可以使用诸如散布运算符之类的东西来复制整个对象,而不必手动设置每个对象:

const x = state.someArray.slice();
x[1] = "potato";
return {...state, someArray:x}

但是要回答您的担忧,是的,您确实必须在更改状态时重新制作该状态的全新副本。通常这不是问题,也不需要太多时间。如果您的状态树是巨大的,那么解决方案应该将该树分成单独的化简器,这样,在更改状态时,您只需复制和替换树的一部分即可。

答案 1 :(得分:0)

1:如果您的状态为去耦,则应使用combineReducers 这是递归的

2:如果没有,则应使用es6 destructuring

3:此外,您还应该考虑您的状态结构。(取决于您的reducer代码,我建议...)

基于2,例如

const mainReducer = (state = {},action) => {
    switch(action.type) {
    case NUMBER_PRESSED:
        if (state.currentOperator===1) return {
           ...state,
           operator1: state.operator1 + action.payload,
           display: 'operator1'
        }
        if(state.currentOperator===2) return {
           ...state,
           operator2: state.operator2 + action.payload,
           display: 'operator2'
        }
        return state
    default: return state;
    }
}

如果程序设计正确,它仍然很大……产品设计?