React Redux - 混淆使用功能组件与 useDispatch 与 Class 组件和 mapStateToProps
React Redux - Confusion on Using Functional Component with useDispatch vs Class Component and mapStateToProps
我正在尝试让用户能够从所有可能的项目列表中单击一个项目,并打开一个模式来显示有关该项目的数据(包括他们当前拥有的数量)和按钮 increment/decrement那个数额。
据我了解,因为我只是显示正在传入的数据,然后分派一个操作来更新商店,所以我应该使用功能组件来显示数据并使用 Dispatch 来调用商店操作。
目前,当我更新商店时,我在 Redux 调试工具中看到了变化,但在我重新打开它之前,变化不会反映在模态中。虽然我一直在寻找这个问题的答案,但我看到许多类似的问题,但它们都使用 Class 组件和 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
}
}
当您 return 更新状态时,请检查您的传播运算符。您可能需要深度克隆旧状态,具体取决于它有多少嵌套对象。
The docs 有更多关于浅克隆对象的信息。
深度克隆状态对象将帮助您摆脱:
let inventoryCopy = { ...state.inventory }
我正在尝试让用户能够从所有可能的项目列表中单击一个项目,并打开一个模式来显示有关该项目的数据(包括他们当前拥有的数量)和按钮 increment/decrement那个数额。
据我了解,因为我只是显示正在传入的数据,然后分派一个操作来更新商店,所以我应该使用功能组件来显示数据并使用 Dispatch 来调用商店操作。
目前,当我更新商店时,我在 Redux 调试工具中看到了变化,但在我重新打开它之前,变化不会反映在模态中。虽然我一直在寻找这个问题的答案,但我看到许多类似的问题,但它们都使用 Class 组件和 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
}
}
当您 return 更新状态时,请检查您的传播运算符。您可能需要深度克隆旧状态,具体取决于它有多少嵌套对象。
The docs 有更多关于浅克隆对象的信息。
深度克隆状态对象将帮助您摆脱:
let inventoryCopy = { ...state.inventory }