【问题标题】:redux-toolkit -- Type error: "unit" is read-onlyredux-toolkit -- 类型错误:“unit”是只读的
【发布时间】:2021-07-10 08:21:28
【问题描述】:

我在这个项目中使用 react-redux 和 redux-toolkit。我想将商品添加到购物车。如果购物车中已经有相同的商品,只需增加单位。错误发生在切片上,所以这里只显示切片。


const CartListSlice = createSlice({
    name: 'cartItem',
    initialState,
    reducers: {
      addToCart: (state, action) => {
        let alreadyExist = false;
// get a copy of it to avoid mutating the state
        let copyState = current(state.cartItem).slice();
        // loop throught the cart to check if that item is already exist in the cart
        copyState.map(item => {
              if (item.cartItem._id === action.payload._id) {
                alreadyExist = true;
                item.unit += 1  // <--- Error occurs here
              }
            })
        
// If the item is not exist in the cart, put it in the cart and along with its unit
        if (alreadyExist === false) {
          state.cartItem.push({
            cartItem: action.payload, 
            unit: 1
          });
        }
      },
    }
});

我收到一个类型错误,告诉我unit 是只读的。 我怎样才能更新“单位”变量,以便它在它应该增加的时候增加。

【问题讨论】:

  • 你能告诉我们initialState吗?另外,你能给我们一个codesandbox上的代码示例吗?
  • 哦,当然,const initialState = { cartItem: [], }
  • 您是否尝试过摆脱 copyState 并在您的 addToCart 减速器函数中使用 state.cartItem
  • 没有current。只需删除 current,其余的留下,让我们知道它是否有效
  • 哦,谢谢,删除 copyState 后,它可以工作了。非常感谢您帮助我。

标签: react-redux redux-toolkit


【解决方案1】:

在 React Toolkit 的 createSlice 中,您可以直接修改 state,甚至应该这样做。所以不要创建副本,只需修改它。 事实上,这个错误可能在某种程度上源于使用current 制作该副本。

See the "Writing Reducers with Immer" documentation page on this

同时,一个建议:

const CartListSlice = createSlice({
    name: 'cartItem',
    initialState,
    reducers: {
      addToCart: (state, action) => {
        const existingItem = state.find(item => item.cartItem._id === action.payload._id)
        if (existingItem) {
          item.unit += 1
        } else {
          state.push({
            cartItem: action.payload, 
            unit: 1
          });
        }
      },
    }
});

【讨论】:

  • 感谢您的建议。我试过你的代码,发现“item”是未定义的,我想你忘了把它包装在这个代码中:current(state.cartItem).map(item =&gt; {}顺便说一句,不走运,代码不起作用,但感谢你的帮助
  • 我使用回我的代码,但这次我不使用 copyState。删除 copyState 后它可以工作,感谢您的帮助。
  • 我更正了我的答案,它需要是.find(item -&gt; item.... 而不是.find(item...
【解决方案2】:

你不需要线:

let copyState = current(state.cartItem).slice();

不要使用copyState,而是使用state.cartItem.map

正如@phry 所说,你应该直接改变state,因为redux-toolkit 在后台使用immerJS 来处理突变。

【讨论】:

  • 是的,不需要```current(state.cartItem)```,非常感谢你的帮助
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多