Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React-Redux-将功能组件与useDispatch与Class组件和mapStateToProps一起使用时出现混淆_Javascript_Reactjs_Redux_Store - Fatal编程技术网

Javascript React-Redux-将功能组件与useDispatch与Class组件和mapStateToProps一起使用时出现混淆

Javascript React-Redux-将功能组件与useDispatch与Class组件和mapStateToProps一起使用时出现混淆,javascript,reactjs,redux,store,Javascript,Reactjs,Redux,Store,我试图让用户能够从所有可能的项目列表中单击一个项目,并打开一个模式以显示该项目的数据(包括当前数量)和增加/减少该数量的按钮 据我所知,由于我只是显示传入的数据,然后分派一个操作来更新存储,所以我应该使用一个功能组件来显示数据,并使用Dispatch来调用存储操作 当前,当我更新存储时,我在Redux调试工具中看到了更改,但在重新打开它之前,更改不会反映在模式中。虽然我一直在寻找答案,但我看到许多类似的问题,但它们都使用类组件和mapStateToProps(例如)。我认为最佳实践是使用功能组件

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

据我所知,由于我只是显示传入的数据,然后分派一个操作来更新存储,所以我应该使用一个功能组件来显示数据,并使用Dispatch来调用存储操作

当前,当我更新存储时,我在Redux调试工具中看到了更改,但在重新打开它之前,更改不会反映在模式中。虽然我一直在寻找答案,但我看到许多类似的问题,但它们都使用类组件和mapStateToProps(例如)。我认为最佳实践是使用功能组件,除非需要。我是否错误地认为,如果我从功能组件中的存储中获得一个值,它应该在更改时更新

代码片段

  • 对话

返回更新状态时,请检查排列运算符。根据嵌套对象的数量,可能需要深度克隆旧状态

了解有关浅层克隆对象的详细信息

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


让inventoryCopy={…state.inventory}

您可以拥有一个无状态功能组件,其中包含一个从容器传递到其中的操作创建者;它不需要是一个类。所以你的计数没有被更新或者整个数据没有被显示?你能发布你的商店状态吗?我给出的答案很模糊,因为我不知道state对象是什么样子的。Store有一个用户缩减器,它是一个具有不同类别的对象,如键(如衣服),在每个类别中可能有子类别。也许克隆是个问题,这是有道理的。我只是更新了我的操作,在我的存储的每个级别创建一个副本,然后更新了相关级别,并将其反馈到存储的更高级别,这就解决了它。非常感谢!是的,你改变了你的状态。我鼓励您开始使用我们的新功能,它在检测到突变时会抛出错误,还允许您编写更简单的还原逻辑。
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
    }
}