使用 useContext 添加和删除数据以及计数 - React - Typescript
adding and removing data and counting with useContext - React - Typescript
我想用一个简单的例子来理解 useContext...
我并没有把整个代码放在这里,而是只放了相关的片段,完整的 code is on codesandbox
我有一个包含两个组件的页面。左边是一个列表。右边是一个容器。当我单击项目下方的“添加”按钮时,它们会出现在右侧的组件容器中。
之后,可以单击列表容器中的提交按钮,该按钮将路由到带有项目列表的另一个组件。可以从那里删除项目。
我正在尽一切努力学习如何在整个 React 应用程序中共享属性。我有几个问题:
- 当我添加元素时,如果名称已经包含在内。我不想显示它十次。相反,我想显示它一次,然后在它旁边显示它被添加了多少次。由于 setItemList 在这里的工作方式,我很难做到这一点:
const addItem = useCallback((item) => {
setCounter((prev) => ({
...prev,
[item.name]: (prev[item.name] || 0) + 1
}));
setItemList((prev) => [...prev, item]);
}, []);
这就是我在列表组件中添加的方式:
const addItemToItemList = (item: Item) => {
/*if (!itemList.includes(item))*/ addItem(item);
};
我将 if 语句注释掉,以便能够多次添加一个项目,但它会一遍又一遍地出现,而不是只出现一次(旁边有计数器)
我的第二个问题是我不知道如何访问第二个计数器。我什至不知道如何使用简单的 console.log...
访问它
最后,目前,如果我在我的列表容器中添加相同的东西三次然后提交,在最后一页上,当我点击删除时,它会立即删除所有这些,而显然我只想删除一个。我想这是因为我的 removeItem 与名称一起使用,但我想不出任何其他方法来实现它...
const removeItem = useCallback(
(itemName) =>
setItemList((prev) => prev.filter((it) => it.name !== itemName)),
[]
);
无论如何,我期待得到一些技巧和提示。到目前为止,享受 React Hooks 之旅。谢谢!
这里有一些架构问题:
首先是,如果你想统计一个项目被添加到列表中的次数,但不想多次添加,你不能在调用时进行检查addItem()
因为您还增加了该函数内的计数器。相反,您应该检查 setItemList()
:
中的重复项
setItemList((prev) => prev.includes(item) ? prev : [...prev, item])
其次,我不明白你想在哪里访问第二个计数器,如果你的意思是在 item.name
旁边的容器中,那么就像你一样从上下文中获取它一样简单用 itemList
:
做了
const { itemList, counter } = useContext(ItemListContext);
// ...
<li key={i}>{counter[item.name]} - {item.name}</li>
// ...
对于第三点,您需要在方法中使用计数器在每次调用时减少它,并且仅在 counter == 0
时才删除该项目。不要忘记将 counter
添加到 useCallback
的依赖项列表中,否则您将始终使用过时的值。
我编辑了你的沙箱 here 以实现预期的结果,使用类似的实现和一个 count
数组,在添加项目时递增它
我想用一个简单的例子来理解 useContext...
我并没有把整个代码放在这里,而是只放了相关的片段,完整的 code is on codesandbox
我有一个包含两个组件的页面。左边是一个列表。右边是一个容器。当我单击项目下方的“添加”按钮时,它们会出现在右侧的组件容器中。
之后,可以单击列表容器中的提交按钮,该按钮将路由到带有项目列表的另一个组件。可以从那里删除项目。
我正在尽一切努力学习如何在整个 React 应用程序中共享属性。我有几个问题:
- 当我添加元素时,如果名称已经包含在内。我不想显示它十次。相反,我想显示它一次,然后在它旁边显示它被添加了多少次。由于 setItemList 在这里的工作方式,我很难做到这一点:
const addItem = useCallback((item) => {
setCounter((prev) => ({
...prev,
[item.name]: (prev[item.name] || 0) + 1
}));
setItemList((prev) => [...prev, item]);
}, []);
这就是我在列表组件中添加的方式:
const addItemToItemList = (item: Item) => {
/*if (!itemList.includes(item))*/ addItem(item);
};
我将 if 语句注释掉,以便能够多次添加一个项目,但它会一遍又一遍地出现,而不是只出现一次(旁边有计数器)
我的第二个问题是我不知道如何访问第二个计数器。我什至不知道如何使用简单的 console.log...
访问它最后,目前,如果我在我的列表容器中添加相同的东西三次然后提交,在最后一页上,当我点击删除时,它会立即删除所有这些,而显然我只想删除一个。我想这是因为我的 removeItem 与名称一起使用,但我想不出任何其他方法来实现它...
const removeItem = useCallback(
(itemName) =>
setItemList((prev) => prev.filter((it) => it.name !== itemName)),
[]
);
无论如何,我期待得到一些技巧和提示。到目前为止,享受 React Hooks 之旅。谢谢!
这里有一些架构问题:
首先是,如果你想统计一个项目被添加到列表中的次数,但不想多次添加,你不能在调用时进行检查addItem()
因为您还增加了该函数内的计数器。相反,您应该检查 setItemList()
:
setItemList((prev) => prev.includes(item) ? prev : [...prev, item])
其次,我不明白你想在哪里访问第二个计数器,如果你的意思是在 item.name
旁边的容器中,那么就像你一样从上下文中获取它一样简单用 itemList
:
const { itemList, counter } = useContext(ItemListContext);
// ...
<li key={i}>{counter[item.name]} - {item.name}</li>
// ...
对于第三点,您需要在方法中使用计数器在每次调用时减少它,并且仅在 counter == 0
时才删除该项目。不要忘记将 counter
添加到 useCallback
的依赖项列表中,否则您将始终使用过时的值。
我编辑了你的沙箱 here 以实现预期的结果,使用类似的实现和一个 count
数组,在添加项目时递增它