React Redux-将功能组件与useDispatch和类组件以及mapStateToProps结合使用

时间:2020-02-07 17:11:52

标签: javascript reactjs redux store

我正在尝试让用户能够从所有可能的项目列表中单击一个项目,并有一个模式打开以显示有关该项目的数据(包括其当前的数量)和按钮以增加/减少该金额

据我了解,由于我只是显示正在传递的数据,然后调度一个操作来更新商店,因此我应该使用功能组件来显示数据,并使用useDispatch调用商店操作。

当前,当我更新商店时,我在Redux调试工具中看到了更改,但是更改直到重新打开后才反映在模式中。尽管我一直在寻找答案,但我看到了许多类似的问题,但是它们都使用类组件和mapStateToProps(例如this post)。我认为最佳实践是除非有必要,否则使用功能组件。我是否认为如果我从功能组件的存储中获取价值,应该在更改时进行更新,这是错误的吗?

代码段

  • 对话框
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
    }
}

1 个答案:

答案 0 :(得分:1)

返回更新状态后,请检查您的点差运算符。您可能需要根据其具有多少个嵌套对象来深克隆旧状态。

webApplication了解有关浅克隆对象的更多信息。

深度克隆状态对象将帮助您摆脱:

let inventoryCopy = { ...state.inventory }