簡體   English   中英

為什么我的 Redux Toolkit 減速器狀態會發生變化?

[英]Why is my Redux Toolkit reducer mutating state?

因此,出於某種原因,下面的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'
  }
}

默認情況下, immer不適用於類實例。 不過,您可以將它們標記為可immerable

但一般來說,你首先不應該把類實例放在你的 Redux 存儲中,請參閱Redux 樣式指南

來自 redux 工具包站點的equipItemById減速器和第一個示例減速器是不同的。 在這個例子中,一個原始值發生了變化,在你的用例中,一個對象發生了變化,並且 immer 可以並且確實跟蹤對象的變化。

equipItemById實際上具有可以改變狀態的示例 reducer 的模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM