[英]Is this exhaustive-deps eslint rule correct?
I know that there are many existing questions about the exhaustive-deps
Eslint rule.我知道关于
exhaustive-deps
-deps Eslint 规则存在许多问题。 However, my question is about a very specific case, so I think it has a place here.但是,我的问题是关于一个非常具体的案例,所以我认为它在这里占有一席之地。
The situation:情况:
On a user's profile page, I show posts they've made to the website:在用户的个人资料页面上,我显示了他们在网站上发布的帖子:
const [postedResources, setPostedResources] = useState<Resource[] | null>(null);
[...]
useEffect(() => {
async function loadPostedResources() {
setPostedResourcesLoadingError(false);
if (!postedResources) setPostedResourcesLoading(true);
try {
const response = await TutHubApi.fetchResourcesPostedByUser(profileUser._id, postedResourcesCurrentPage);
setPostedResources(response.resources);
setPostedResourcesTotalCount(response.totalCount);
setPostedResourcesPageCount(response.pageCount);
} catch (error) {
console.log(error);
setPostedResourcesLoadingError(true);
} finally {
setPostedResourcesLoading(false);
}
}
loadPostedResources();
}, [profileUser, postedResourcesCurrentPage]);
This line:这一行:
if (!postedResources) setPostedResourcesLoading(true);
makes the page not show a loading spinner if there are already resources loaded, which is the case when we load another page of results (as opposed to loading the first page when we first open the profile of a user).如果已经加载了资源,则使页面不显示加载微调器,当我们加载另一页结果时就是这种情况(而不是在我们第一次打开用户配置文件时加载第一页)。
Now Eslint warns me to add postedResources
as a dependency.现在 Eslint 警告我添加
postedResources
作为依赖项。 But 1. this would cause an infinite loop in useEffect
and 2. I absolutely don't see the need to add it.但是 1. 这会导致
useEffect
和 2. 我绝对没有必要添加它。 I only want to look at this value the very moment we load the next batch of results.我只想在我们加载下一批结果的那一刻查看这个值。
Am I missing something?我错过了什么吗? Can my current setup cause any bugs I'm not aware of?
我当前的设置会导致我不知道的任何错误吗?
Even though it might work in this case, omitting dependencies is generally not recommended, since it might be source of unexpected bugs.尽管它可能在这种情况下工作,但通常不建议忽略依赖项,因为它可能是意外错误的来源。
The linter requires this rule to make sure your code will not reference stale values from previous renders. linter 需要此规则以确保您的代码不会引用以前渲染中的陈旧值。
I would recommend reading this article from Dan Abramov which shows examples of possible problems when omitting dependencies, and also solutions - https://overreacted.io/a-complete-guide-to-useeffect/#dont-lie-to-react-about-dependencies我建议阅读 Dan Abramov 的这篇文章,其中显示了省略依赖项时可能出现的问题的示例以及解决方案 - https://overreacted.io/a-complete-guide-to-useeffect/#dont-lie-to-react-关于依赖
In this particular example, you might try:在此特定示例中,您可以尝试:
Modifying the postedResourcesLoading
state to use useReducer
hook, which is shown in the article as one of the possibilities.修改
postedResourcesLoading
状态以使用useReducer
钩子,这在文章中显示为一种可能性。
Using approach with useRef
hook, described in react docs - https://reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often .使用带有
useRef
钩子的方法,在反应文档中描述 - https://reactjs.org/docs/hooks-faq.html#what-c an-i-do-if-my-effect-dependencies-change-too-often 。 This way, you can store the latest state in a ref, and since ref never changes its reference, it is not required to be listed in useEffect dependencies.这样,您可以将最新状态存储在 ref 中,并且由于 ref 永远不会更改其引用,因此不需要将其列在 useEffect 依赖项中。
const [postedResources, setPostedResources] = useState<Resource[] | null>(null);
const postedResourcesRef = useRef(postedResources);
useEffect(() => {
postedResourcesRef.current = postedResources;
});
useEffect(() => {
async function loadPostedResources() {
setPostedResourcesLoadingError(false);
if (!postedResourcesRef.current) setPostedResourcesLoading(true);
try {
const response = await TutHubApi.fetchResourcesPostedByUser(profileUser._id, postedResourcesCurrentPage);
setPostedResources(response.resources);
setPostedResourcesTotalCount(response.totalCount);
setPostedResourcesPageCount(response.pageCount);
} catch (error) {
console.log(error);
setPostedResourcesLoadingError(true);
} finally {
setPostedResourcesLoading(false);
}
}
loadPostedResources();
}, [profileUser, postedResourcesCurrentPage]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.