Redux Toolkit移除数组项异常:全部数据被清空问题求助
问题根源与修复方案
核心问题
你遇到的取消勾选后数组清空的问题,是由两个关键错误导致的:
Redux Slice中的属性拼写与访问错误
- 添加产品时,你dispatch的
checkoutaction传入的payload是{products: itemsArr},因此state.value.products数组中的每个元素是{products: {productName: ...}}的嵌套结构。 - 但在
removeItemreducer里,你错误地拼写了productName为produdctName,同时没有正确访问嵌套的products.productName,导致filter条件完全不匹配,最终数组被错误清空。
- 添加产品时,你dispatch的
Checkbox组件中的数据属性名错误
const items = products.items里的items是笔误,你的Redux state中存储产品的属性是products,应该改为const items = products.products。
修正后的代码
1. 修复Redux Slice代码
import { createSlice } from "@reduxjs/toolkit"; const initialState = { value: { products: [], } } export const checkOut = createSlice({ name: "checkout", initialState, reducers: { checkout: (state, action) => { state.value.products.push(action.payload) }, removeItem: (state, action) => { // 修正拼写错误,同时正确访问嵌套的productName属性 state.value.products = state.value.products.filter(item => item.products.productName !== action.payload.products.productName ) } } }) export const { checkout, removeItem } = checkOut.actions export default checkOut.reducer
2. 修复Checkbox组件代码
const products = useSelector((state) => state.prodSlice.value) const handleChange = (event) => { const isActive = event.target.checked const itemName = event.currentTarget.id // 修正属性名,从items改为products const items = products.products // 用find代替forEach,更高效地定位目标产品 const targetItem = items.find(item => item.products.productName === itemName) if (targetItem) { if (isActive) { dispatch(checkout({products: targetItem.products})) } else { dispatch(removeItem({products: targetItem.products})) } } }
更优简化方案
建议简化Redux的存储结构,直接存储产品对象数组,避免多余的嵌套层级,让代码更简洁:
优化后的Redux Slice
import { createSlice } from "@reduxjs/toolkit"; const initialState = { value: { products: [], } } export const checkOut = createSlice({ name: "checkout", initialState, reducers: { checkout: (state, action) => { // 直接存入产品对象,去掉外层products包裹 state.value.products.push(action.payload) }, removeItem: (state, action) => { // 直接通过productName过滤 state.value.products = state.value.products.filter(item => item.productName !== action.payload.productName ) } } }) export const { checkout, removeItem } = checkOut.actions export default checkOut.reducer
优化后的Checkbox组件代码
const products = useSelector((state) => state.prodSlice.value) const handleChange = (event) => { const isActive = event.target.checked const itemName = event.currentTarget.id const items = products.products const targetItem = items.find(item => item.productName === itemName) if (targetItem) { if (isActive) { dispatch(checkout(targetItem)) } else { // 仅传入productName即可,无需整个对象 dispatch(removeItem({productName: itemName})) } } }
内容的提问来源于stack exchange,提问作者Parzival
相关产品推荐
相关产品推荐

