You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux Toolkit如何更新initialState中未预定义的状态对象

问题背景

数据为动态传入,无法提前知晓其值以在initialState中完成初始赋值,触发运行时报错。
核心疑问:如果initialState中原本不存在对应对象,要如何更新state中的该对象?


报错信息
filteringSlice.ts:12 

Uncaught TypeError: Cannot read properties of undefined (reading 'products')
    at addFilter (filteringSlice.ts:12:1)
    at createReducer.ts:280:1
    at produce (immerClass.ts:94:1)
    at createReducer.ts:279:1
    at Array.reduce (<anonymous>)
    at reducer (createReducer.ts:246:1)
    at reducer (createSlice.ts:325:1)
    at combination (redux.js:560:1)
    at k (<anonymous>:2235:16)
    at D (<anonymous>:2251:13)
Action调用示例
onChange={(selectedValue) => {
  dispatch(
    addFilter({
      products: { category__name: { filter: selectedValue } },
    })
  );
}}
Slice原代码定义
import { createSlice } from "@reduxjs/toolkit";
const initialState = {} as any;
const filteringSlice = createSlice({
  name: "filtering",
  initialState,
  reducers: {
    addFilter: (state, action) => {
      const key = Object.keys(action.payload)[0];
      const key2 = Object.keys(action.payload[key])[0];
      const values = Object.values(action.payload[key])[0];
      //@ts-ignore
      state.filters[key][key2] = { ...state.filters[key][key2], ...values };
    },
  },
});
const { reducer, actions } = filteringSlice;
export const { addFilter } = actions;
export default reducer;

报错原因

  1. 初始initialState是空对象,根本没有filters属性,第一次执行addFilter时直接访问state.filters[key],相当于读取undefined[key],直接触发类型错误。
  2. 动态key场景下没有做上层对象的存在性校验,直接访问嵌套属性,只要上层对象不存在就会抛错。

修复方案

  1. 先给initialState补上基础的filters空对象结构,避免最上层属性不存在。
  2. 赋值前先判断每层动态key对应的对象是否存在,不存在就初始化为空对象,再做属性合并,适配动态传入的任意key场景。

修复后的Slice代码:

import { createSlice } from "@reduxjs/toolkit";
// 先初始化基础的filters结构
const initialState = {
  filters: {}
} as any;
const filteringSlice = createSlice({
  name: "filtering",
  initialState,
  reducers: {
    addFilter: (state, action) => {
      const key = Object.keys(action.payload)[0];
      const key2 = Object.keys(action.payload[key])[0];
      const values = Object.values(action.payload[key])[0];
      
      // 动态key不存在时先初始化空对象,避免读取undefined属性
      if (!state.filters[key]) {
        state.filters[key] = {};
      }
      if (!state.filters[key][key2]) {
        state.filters[key][key2] = {};
      }

      state.filters[key][key2] = { ...state.filters[key][key2], ...values };
    },
  },
});
const { reducer, actions } = filteringSlice;
export const { addFilter } = actions;
export default reducer;

如果不想写多层if判断,也可以用简写方式:

addFilter: (state, action) => {
  const key = Object.keys(action.payload)[0];
  const key2 = Object.keys(action.payload[key])[0];
  const values = Object.values(action.payload[key])[0];
  
  state.filters[key] = state.filters[key] || {};
  state.filters[key][key2] = {
    ...(state.filters[key][key2] ?? {}),
    ...values
  };
}

内容的提问来源于stack exchange,提问作者skelaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 21:12:35