[英]Data Fetching Using useEffect() And useCallback In React
I'm looking for the most optimal way to fetch data using useEffect()
when the fetch function is used in more than one place.当 fetch 函数在多个地方使用时,我正在寻找使用
useEffect()
获取数据的最佳方法。
Currently, I have a parent component ( ItemContainer
) and a child component ( SearchBar
).目前,我有一个父组件(
ItemContainer
)和一个子组件( SearchBar
)。 ItemContainer
should fetch the all the possible list of items using getItemList()
functions. ItemContainer
应该使用getItemList()
函数获取所有可能的项目列表。 I'm executing this function within the useEffect()
during the first render, and also passing it down to SearchBar
component, so that when a user submits a search term, it will update itemList
state by triggering getItemList()
in ItemContainer
.我在第一次渲染期间在
useEffect()
中执行此函数,并将其传递给SearchBar
组件,这样当用户提交搜索词时,它将通过触发ItemContainer
中的getItemList()
来更新itemList
状态。
This actually works just as I expected.这实际上就像我预期的那样工作。 However, my issue is that
但是,我的问题是
getItemList()
outside the useEffect()
in this kind of situation.useEffect()
getItemList()
。 From what I've been reading (blog posts, react official docs) it is generally recommended that data fetching function should be defined inside the useEffect()
, although there could be some edge cases.useEffect()
中定义数据获取功能,尽管可能存在一些边缘情况。 I'm wondering if my case applies as this edge cases.useCallback
?useCallback
依赖项数组留空吗? I tried filling it out using searchTerm
, itemList
, but none of them worked - and I'm quite confused why this is so.searchTerm
、 itemList
填写它,但它们都不起作用——我很困惑为什么会这样。 I feel bad that I don't fully understand the code that I wrote.我对自己写的代码没有完全理解感到很遗憾。 I would appreciate if any of you could enlighten me with what I'm missing here...
如果你们中的任何人能告诉我我在这里缺少的东西,我将不胜感激......
const ItemContainer = () => {
const [itemList, setItemList] = useState([]);
const getItemList = useCallback( async (searchTerm) => {
const itemListRes = await Api.getItems(searchTerm);
setItemList(itemListRes)
}, []);
useEffect(() => {
getItemList();
}, [getItemList]);
return (
<main>
<SearchBar search={getItemList} />
<ItemList itemList={itemList} />
</main>
)
}
const SearchBar = ({ search }) => {
const [searchTerm, setSearchTerm] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
search(searchTerm);
setSearchTerm('');
}
const handleChange = (e) => {
setSearchTerm(e.target.value)
}
return (
<form onSubmit={handleSubmit}>
<input
placeholder='Enter search term...'
value={searchTerm}
onChange={handleChange}
/>
<button>Search</button>
</form>
)
}
Here are my answers.这是我的答案。
Yes, it is okay.是的,没关系。 What's inside
useCallback
is "frozen" respect to the many ItemConteiner
function calls that may happen. useCallback
里面的内容是对可能发生的许多ItemConteiner
函数调用的“冻结”。 Since the useCallback
content accesses only setItemList
, which is also a frozen handler, there'll be no problems.由于
useCallback
内容仅访问setItemList
,这也是一个冻结的处理程序,因此不会有任何问题。
That's also correct, because an empty array means "dependent to nothing".这也是正确的,因为空数组意味着“不依赖于任何东西”。 In other words, the callback is created once and keeps frozen for all the life of the
ItemContainer
.换句话说,回调创建一次,并在
ItemContainer
的整个生命周期内保持冻结状态。
Instead, this is something weird:相反,这很奇怪:
useEffect(() => {
getItemList();
}, [getItemList]);
It works, but it has a very little sense.它有效,但它的意义很小。 The
getItemList
is created once only, so why make an useEffect
depending to something never changes? getItemList
只创建一次,那么为什么要让useEffect
依赖于永远不会改变的东西呢?
Make it simpler, by running once only:让它更简单,只运行一次:
useEffect(() => {
getItemList();
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.