Я пытаюсь, чтобы пользователь мог щелкнуть элемент из списка всех возможных элементов и открыть модальное окно для отображения данных об этом элементе (включая текущее количество, которое он имеет) и кнопок для увеличения / уменьшения этого количества. .
Насколько я понимаю, поскольку я просто показываю данные, которые передаются, а затем отправляю действие для обновления хранилища, я должен использовать функциональный компонент для отображения данных и использовать Dispatch для вызова действия хранилища.
В настоящее время, когда я обновляю магазин, я вижу изменения в инструментах отладки Redux, но это изменение не отражается в модальном режиме, пока я не открою его снова. Пока я искал ответы на эти вопросы, я вижу много похожих вопросов, но все они используют компоненты класса и mapStateToProps (например, этот пост ). Я думал, что передовой практикой является использование функциональных компонентов без необходимости. Неправильно ли я думать, что если я получаю значение из хранилища в функциональном компоненте, оно должно обновляться при изменении?
Фрагменты кода
export default function ItemDialog({
...
selectedItem,
}) {
const dispatch = useDispatch()
const inventory = useSelector(
state => state.user.inventory
)
let userItem = inventory.find(
userItem => userItem.name === selectedItem.name
)
const changeItemCount = (item, change) => {
item.change = change
dispatch({
type: "USER_INVENTORY_UPDATED",
payload: item
})
}
const showQuantity = userItem => {
return userItem.quantity > 0 ? `(${userItem.quantity})` : ""
}
...
render(
<p className="text-xl text-center font-semibold">
{selectedItem.name}
</p>
<p className="text-center font-light">
{showQuantity(userItem)}
</p>
...
<AddBoxIcon
onClick={() => changeItemCount(selectedItem, 1)}
/>
)
const userReducer = (state = InitialUserState, action) => {
let inventoryCopy = { ...state.inventory }
switch (action.type) {
case "USER_INVENTORY_UPDATED":
let category = action.payload.category
let updatedItemIndex = inventoryCopy[category].findIndex(
item => item.name === action.payload.name.toUpperCase()
)
// If item is already there
if (updatedItemIndex >= 0) {
inventoryCopy[category][updatedItemIndex].quantity +=
action.payload.change
} else {
// If item needs to be added to inventory category
let newItem = {
name: action.payload.name,
quantity: action.payload.change
}
inventoryCopy[category].push(newItem)
}
return {
...state,
inventory: inventoryCopy
}
...
default:
return state
}
}