reactjs Redux Toolkit中的state.filter为什么不过滤数组?

eh57zj3b  于 2023-01-17  发布在  React
关注(0)|答案(3)|浏览(147)

我正在使用Redux Toolkit创建一个目标跟踪器,用于学习目的。目标保存在一个数组中,我可以将新值推送到该数组中,没有任何问题,但当我尝试对同一个数组执行state.filter时,该值没有被删除。Redux devtools显示deleteGoal正在运行,但它没有删除任何内容。
我试着使用splice、过滤current(state)、记录状态,并在不同的文件中放置调试器,我注意到状态记录是代理,但如果这就是问题所在,为什么state.push()可以工作而state.filter()不能?
数组(在切片中):

const initialState = [
    {
        id: 1,
        input: 'drink water',
        achieved: true
    },
    {
        id: 2,
        input: 'in bed by 11:15',
        achieved: true
        },
    {
        id: 3,
        input: 'study 2hrs',
        achieved: true
    },
]

这些行动:

export const goalsSlice = createSlice({
  name: 'goals',
  initialState,
  reducers: {
    addGoal: (state, action) => {
        state.push(action.payload)
      },
    deleteGoal: (state, action) => {
      const goalId = action.payload
      state.filter((goal) => goal.id !== goalId)
      console.log(current(state))
    },
  },
})

渲染它的组件:

<Text
        fontSize="3xl"
        fontWeight={600}
        >your goals:</Text>
            {goals.map((goal, index) => (
                    <li 
                    key={index}
                    onDoubleClick = {goal => {
                        dispatch(deleteGoal(goal.target.textContent))
                        // console.log(goal)
                        // console.log(goal.target.textContent)
                    }}
                    className='goal-text'
                    >
                        
                        {goal.input}
                    </li> 
            
        ))}
xmakbtuz

xmakbtuz1#

state.filter()未按预期工作,因为您需要返回结果以更新状态;不改变它的位置。例如

return state.filter((goal) => goal.id !== goalId)

state.push() * 确实 * 如您所期望的那样工作,因为它是就地更改状态而不是返回值。这可能与Redux的最佳实践相悖-您的addGoal函数可以更改为类似于

addGoal: (state, action) => {
  // return a new array, don't modify the existing state in place
  return [
    ...state, // copy the current array of goals
    (action.payload) // add the new goal
  ]
},

有关https://redux.js.org/style-guide/#do-not-mutate-state详细信息,请访问www.example.com

plicqrtu

plicqrtu2#

由于filter()不修改阵列,而是创建阵列的卷影副本,因此deleteGoal中的预期操作可能是:

// Only for redux-toolkit

state = state.filter((goal) => goal.id !== goalId)

根据redux-toolkit文档(与Redux相对):
为了简化操作,createReducer使用immer来编写reducer,就像它们直接改变状态一样。实际上,reducer接收一个代理状态,将所有的改变转换为等效的复制操作。
更多关于redux-toolkit如何允许"变异"更新Reducer中不可变状态的示例:createSlice.

7ajki6be

7ajki6be3#

Redux tookit使用immer的引擎盖下,允许您编写可变语法。我想这是必须的事情,不要写它不变的代码,否则没有使用immer。我面临同样的问题,简单地返回新的数组从过滤器。

erase: (state, action) => {
      return state.filter(
        (element) => JSON.stringify(element) !== JSON.stringify(action.payload)
      );

'它删除了不匹配的对象。

相关问题