首页 > 解决方案 > 为什么我的 Redux Toolkit reducer 处于变异状态?

问题描述

因此,出于某种原因,下面的equipItemById减速器似乎处于变异状态——尽管它基本上是来自 Redux Toolkit 示例的逐字记录:

在此处输入图像描述

完整切片如下:

import { createSlice } from '@reduxjs/toolkit';
import Item from '../../../Entities/Item/Item';

const initialState = {
  itemsById: [
    new Item('weapon', 'oak_stave', 0),
    new Item('chest', 'basic_robes', 0),
    new Item('feet', 'basic_boots', 0),
    new Item('head', 'basic_circlet', 0),
    new Item('consumable', 'potion_of_healing', 0),
    new Item('consumable', 'potion_of_healing', 1),
    new Item('consumable', 'potion_of_healing', 1),
    new Item('weapon', 'rusty_sword', 5),
    new Item('weapon', 'iron_sword', 5),
    new Item('weapon', 'steel_sword', 5),
    new Item('weapon', 'enchanted_steel_sword', 5),
  ],
  inTrade: false,
  actorInTradeById: undefined,
  itemsPlayerWantsToTradeById: [],
  itemsOtherActorWantsToTrade: [],
  itemsByLocationName: {
    centralSquare: [new Item('weapon', 'enchanted_steel_sword')],
  },
};

const itemSlice = createSlice({
  name: 'items',
  initialState: initialState,
  reducers: {
    addItemToActorFromLocationByIdAndName: (state, action) => {
      const { actorId, item } = action.payload;
      let itemCopy = item;
      item.ownerId = actorId;
      state.itemsById.push(itemCopy);
    },
    equipItemById: (state, action) => {
      const item = state.itemsById.find((item) => item.id === action.payload);
      item.equipped = true;
    },
    unequipItemById: (state, action) => {
      const { itemId } = action.payload;
      const item = state.itemsById.find((item) => item.id === itemId);
      item.equipped = false;
    },
    dropItemFromInventory: (state, action) => {
      const { itemId, locationName } = action.payload;
      const item = state.itemsById.find(
        (item) => item.id === itemId
      );
      item.ownerId = undefined;
      item.equipped = false;
      state.itemsById = state.itemsById.filter(item => item.id !== itemId);
      state.itemsByLocationName[locationName].push(item);
    },
    removeItemFromLocation: (state, action) => {
      const { itemId, locationName } = action.payload;
      state.itemsByLocationName[locationName] = state.itemsByLocationName[
        locationName
      ].filter((item) => item.id !== itemId);
    },
  },
});

export const {
  addItemToActorFromLocationByIdAndName: addItemToActorById,
  equipItemById,
  unequipItemFromActorByIds,
  inventorySetActiveItem,
  equippedSetActiveItem,
  dropItemFromInventory,
  dropItemFromEquipped,
  removeItemFromLocation,
} = itemSlice.actions;
export default itemSlice;

调度被称为:

 dispatch(
    itemSlice.actions.equipItemById(props.item.id)
  );

正如您在下面看到的那样 - 有问题的动作在之前和之后都具有相同的装备属性 - 即使它之前肯定是错误的。

在此处输入图像描述

一个 Item 对象看起来像这样(并且嵌套在 itemsById 数组中)

{
  '0': {
    type: 'weapon',
    id: 0,
    qty: 1,
    equipped: true,
    ownerId: 0,
    name: 'Oak Branch',
    icon: 'fa-staff',
    rarity: 0,
    descDetails: 'Deals an additional 1 damage per hit.',
    desc: 'A simple weapon. Strong and sturdy. No man turns down a stout wooden branch, when the alternative is an empty hand to face the sharp steel of a bandit.',
    stats: {},
    value: 1,
    slot: 'weapon_main',
    addedDmgString: '1'
  }
}

标签: javascriptreduxreact-reduxredux-toolkit

解决方案


immer默认情况下不适用于类实例。您可以将它们标记为immerable好像。

但一般来说,你不应该首先将类实例放在你的 Redux 存储中,请参阅Redux 样式指南


推荐阅读