简体   繁体   English

这个详尽的 eslint 规则是否正确?

[英]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:在此特定示例中,您可以尝试:

  1. Modifying the postedResourcesLoading state to use useReducer hook, which is shown in the article as one of the possibilities.修改postedResourcesLoading状态以使用useReducer钩子,这在文章中显示为一种可能性。

  2. 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.

相关问题 useEffect 和 ESlint 穷举-deps 规则 - useEffect and ESlint exhaustive-deps rule useEffect 依赖数组和 ESLint Exclusive-deps 规则 - useEffect dependency array and ESLint exhaustive-deps rule useEffect 详尽-deps 规则令人困惑 - useEffect exhaustive-deps rule is confusing 如何使用React Hooks进行获取; ESLint强制执行“穷举下降”规则,这会导致无限循环 - How to do fetch with React Hooks; ESLint enforcing `exhaustive-deps` rule, which causes infinite loop React Hooks react-hooks/exhaustive-deps eslint 规则似乎过于敏感 - React Hooks react-hooks/exhaustive-deps eslint rule seems overly sensitive 如何在React中使用钩子实现componentDidMount以使其符合EsLint规则“ react-hooks / exhaustive-deps”:“ warn”? - How to implement componentDidMount with hooks in React to be in line with the EsLint rule “react-hooks/exhaustive-deps”: “warn”? 为 SVG viewBox 反应“useViewBox”挂钩失败的 ESLint 规则 exhaustive-deps - React "useViewBox" hook for SVG viewBox failing ESLint rule exhaustive-deps 使用 i18next 时如何处理 ESLint react-hooks 'exhaustive-deps' 规则? - How to handle ESLint react-hooks 'exhaustive-deps' rule when using i18next? ESLint 详尽的-deps:忽略来自 ref 的值 - ESLint exhaustive-deps: ignore value that came from a ref 使用 eslint Exclusive-deps 响应订阅/取消订阅的 useEffect 依赖项 - React useEffect dependencies for subscribe/unsubscribe with eslint exhaustive-deps
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM