简体   繁体   English

React - 更新多个 useEffect / useCallback 依赖项但只调用一次 effect

[英]React - update multiple useEffect / useCallback dependencies but only call effect once

I have a paginated list of data that I am updating based on a filter and an offset (page) When the offset is updated (next/prev page) I hit the API and get new data.我有一个基于过滤器和偏移量(页面)更新的分页数据列表 当偏移量更新(下一页/上一页)时,我点击 API 并获取新数据。 When the filter is updated I reset the offset to 0.当过滤器更新时,我将偏移量重置为 0。

The problem is, when the filter is updated and the offset is updated it causes the useEffect to be fired twice.问题是,当过滤器更新和偏移量更新时,它会导致 useEffect 被触发两次。 Which in turn calls the api twice.依次调用 api 两次。

const [filter, setFilter] = useState('All');
const [offset, setOffset] = useState(0);
onFilterChange = (value) => {
  setFilter(value);
  offset !== 0 && setOffset(0);
}

getDataFromAPI = useCallback(() => {
   const endpoint = `https://example.com/data?filter=${filter}&offset=${offset}`;
   CallApi(endpoint);
}, [offset, filter])

useEffect(getDataFromAPI, [getDataFromAPI]);

I think the fix would be to get rid of useEffect in such case.我认为解决方法是在这种情况下摆脱useEffect Sometimes it is used needlessly.有时它被不必要地使用。 Just call CallApi inside the onFilterChange and onOffsetChange handlers with the new values that were set, and that's it.只需使用设置的新值在onFilterChangeonOffsetChange处理程序中调用CallApi ,就可以了。

Here are some relevant quotes from Dan Abramov:以下是 Dan Abramov 的一些相关引述:

In hindsight, my personal conviction has become that if some effect can't safely over-fire (eg fire twice instead of once), there is a problem.事后看来,我个人的信念是,如果某些效果不能安全地过度发射(例如,发射两次而不是一次),就会出现问题。 Usually things that can't over-fire are related to user actions ("buy", "send", "finish").通常不能过火的事情与用户操作(“购买”、“发送”、“完成”)有关。 Actions start in event handlers.动作在事件处理程序中开始。 Use them!使用它们!

To sum up, if something happens because a user did something, useEffect might not be the best tool.总而言之,如果由于用户做了某事而发生了某些事情,那么 useEffect 可能不是最好的工具。

On the other hand, if an effect merely synchronizes something (Google Map coordinates on a widget) to the current state, useEffect is a good tool.另一方面,如果一个效果只是将某些东西(小部件上的谷歌地图坐标)同步到当前状态,useEffect 是一个很好的工具。 And it can safely over-fire.它可以安全地过度射击。


PS But just to note I thought in your case react would batch the two different set state calls inside the filter change handler (hence call render once), but it seems it doesn't? PS 但请注意,我认为在您的情况下,react 会在过滤器更改处理程序中批处理两个不同的设置状态调用(因此调用渲染一次),但似乎没有? In any case you may still prefer the recommendation in the beginning of my answer to remove useEffect .在任何情况下,您可能仍然更喜欢我回答开头的建议,以删除useEffect

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM