使用 useReducer 更新状态时遇到问题

cyc*_*ion 0 state reactjs

利用 React useReducer 并尝试进行状态更新并在我进行更改时重新渲染。

JSX 调用减速器:

<button onClick={() => dispatch({ type: "DECREMENT", item })} >+</button>
Run Code Online (Sandbox Code Playgroud)

和 useReducer:

const reducer = (state, action) => {
  const { item, type } = action;
  switch (type) {
    case "INCREMENT": {
      const newCart = state;
      const u = { ...item, quantity: item.quantity + 1 };
      const index = newCart.findIndex(eachitem => item.id === eachitem.id);
      newCart.splice(index, 1, u);
      console.log("INCREMENT", newCart);
      return newCart;
    }
    case "DECREMENT": {
      const newCart = state;
      const u = { ...item, quantity: item.quantity - 1 };
      const index = newCart.findIndex(eachitem => item.id === eachitem.id);
      newCart.splice(index, 1, u);
      console.log("DECREMENT", newCart);
      return newCart;
    }
    case "REMOVE": {
      return state.filter(eachitem => item.id !== eachitem.id);
    }
    default: {
      return state;
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

完整代码可以在下面找到。

编辑代码和拳击手示例

GPr*_*ost 5

由于您返回了相同的对象,因此您的减速器无法检测到状态变化。通过比较 prev state value 和 new state 来检测变化,通过===比较或Object.is()比较基本上是一样的东西(不确定是哪一个,可以尝试在 React docs 中找到)。

所以而不是:

const newCart = state;
Run Code Online (Sandbox Code Playgroud)

你需要做:

// shallowly copy the state so now Object.is(newState, prevState) returns false
const newCart = [...state];
...
return newCart
Run Code Online (Sandbox Code Playgroud)

  • 很有道理。我创建了 NewCart 来避免变异,但因为它是一个对象,所以它指向同一个对象(我正在改变它)。通过将状态传播到新对象中,它提供了一个浅拷贝并实际引用了一个新对象。谢谢 (2认同)