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

使用Redux Toolkit更新多层嵌套对象的方法咨询

Redux Toolkit 更新多层嵌套对象的方法

我正在学习React结合Redux开发,目前想用Redux Toolkit更新多层嵌套的对象状态。我已经掌握了单层对象的更新方法,但不清楚如何处理多层嵌套的情况。以下是我的代码示例:

import { createSlice } from '@reduxjs/toolkit';

const initialBannerContentState = {
    bannerContent: {
        bg: {
            id: 0,
            type: 'image',
            url: '',
            height: 0,
            width: 0,
            x: 0,
            y: 0,
            draggable: true,
            deleted: false
        },
        partnerlogo: {
            id: 0,
            type: 'image',
            url: '',
            height: 0,
            width: 0,
            x: 0,
            y: 0,
            draggable: true,
            deleted: false
        }
    }
};

const bannerContentSlice = createSlice({
    name: 'bannercontent',
    initialState: initialBannerContentState,
    reducers: {
        // actions go here
    }
});

export const BannerContentActions = bannerContentSlice.actions;

export default bannerContentSlice.reducer;

补充说明

我所理解的单层对象状态如下:

const initialBannerContentState = {
    id: 1,
    type: 'image',
    // 其他属性
};

而我当前使用的另一种多层状态形式是数组嵌套对象:

const initialBannerContentState = [
    {
        id: 1,
        type: 'image',
        // 其他属性
    },
    {
        id: 2,
        type: 'text',
        // 其他属性
    }
];

解决方案

Redux Toolkit 内置了 Immer 库,允许你在 reducer 中直接"修改"状态(实际是 Immer 帮你生成不可变的新状态),无需手动做深拷贝。针对你提到的两种嵌套场景,具体实现如下:

场景1:对象嵌套对象(如你提供的第一个示例)

直接通过属性路径修改对应值即可,比如更新 bg 的 url 或者 partnerlogo 的 x 坐标:

const bannerContentSlice = createSlice({
    name: 'bannercontent',
    initialState: initialBannerContentState,
    reducers: {
        // 单独更新bg的url
        updateBgUrl: (state, action) => {
            state.bannerContent.bg.url = action.payload;
        },
        // 通用更新某个嵌套对象的属性
        updateBannerItemField: (state, action) => {
            const { itemKey, field, value } = action.payload;
            // itemKey 可以是 'bg' 或 'partnerlogo'
            state.bannerContent[itemKey][field] = value;
        }
    }
});

使用时,调用对应的 action:

// 更新bg的url
dispatch(BannerContentActions.updateBgUrl('https://example.com/bg.jpg'));

// 更新partnerlogo的x坐标
dispatch(BannerContentActions.updateBannerItemField({
    itemKey: 'partnerlogo',
    field: 'x',
    value: 100
}));

场景2:数组嵌套对象(你补充的第二个示例)

通过数组方法找到目标对象后直接修改其属性:

const bannerContentSlice = createSlice({
    name: 'bannercontent',
    initialState: initialBannerContentState, // 这里是数组状态
    reducers: {
        // 根据id更新对象的某个属性
        updateItemFieldById: (state, action) => {
            const { id, field, value } = action.payload;
            const targetItem = state.find(item => item.id === id);
            if (targetItem) {
                targetItem[field] = value;
            }
        },
        // 替换整个对象
        replaceItemById: (state, action) => {
            const { updatedItem } = action.payload;
            const index = state.findIndex(item => item.id === updatedItem.id);
            if (index !== -1) {
                state[index] = updatedItem;
            }
        }
    }
});

使用示例:

// 更新id为1的对象的url
dispatch(BannerContentActions.updateItemFieldById({
    id: 1,
    field: 'url',
    value: 'https://example.com/image1.jpg'
}));

// 替换id为2的整个对象
dispatch(BannerContentActions.replaceItemById({
    updatedItem: {
        id: 2,
        type: 'text',
        content: '新文本内容',
        // 其他属性
    }
}));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 23:15:23