[英]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.