作为练习练习,我正在编写一个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中的部分状态?
您可以使用扩展运算符之类的东西来复制整个对象,而无需手动设置每个对象:
const x = state.someArray.slice();
x[1] = "potato";
return {...state, someArray:x}
但要回答您的问题,是的,您必须在更改状态时制作全新的状态副本。这通常不是问题,也不需要花费太多时间。如果您的状态树是巨大的,那么解决方案应该是将该树拆分为单独的reducer,这样您只需要在更改状态时复制和替换树的部分。
1:如果你的状态是脱钩你应该使用combineReducers这是递归
2:如果没有,你应该使用es6 destructuring
3:更重要的是,你应该考虑你的州结构。(取决于你的减速机代码,我建议......)
以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;
}
}
如果正确的程序设计仍然很大......产品设计?