News for hackers. Stuff that matters.
Re:React: You Might Not Need an Effect by davedx on Thursday March 23, 2023 @08:07AM (#35273421)
> If it's defined within the component scope and not wrapped in useCallback then it does in fact change on every render and the lint error is being raised for good reason.

So I just did some playing around to investigate this further, and it seems to be more subtle than I thought.

If you have a function expression but the expression is not dependent on any outer scoped variables, the linter does not complain that you didn't specify the function itself as a dependency in useEffect. Example:

```

  let bar = "bar";

  const setResult = (result: string) => {
    // Won't trigger "exhaustive-deps"
    setBio(result);
    // Will trigger "exhaustive-deps"
    if (bar === "1") setBio(result);
  };

  useEffect(() => {
    setResult("");
  }, [person]);
```

So there's some quite sophisticated analysis of the AST going on in the lint rule.

I still think that this rule is too complicated for a linter. (Bugs like inter-dependencies in your data and code should be caught by unit tests).

But it's technically pretty impressive.

Edit: I did some more investigations.

If I make a function that depends on something very unpure (like checking window.location), the linter fires if the unpure function is in the outer scope of the hook, but not if it isn't. Even though the dependency is the same. So the linter rule can only identify locally scoped dependencies I think.

Re:React: You Might Not Need an Effect by joshribakoff on Thursday March 23, 2023 @08:18AM (#35273544)
> Bugs like inter-dependencies in your data and code should be caught by unit tests

Why write a ton of unit tests for what a static check can just do “for free?”. Not sure i follow your logic. I agree React can feel like a nuisance, but the lint rule itself is not the issue i think you have, it sounds like your issue is just with hooks.

Re:React: You Might Not Need an Effect by Jcampuzano2 on Thursday March 23, 2023 @08:47AM (#35273885)
Its not necessarily that the function depends on something 'very unpure', its if it depends on anything which is non-primitive that is created or assigned within the component fn body.

window.location returns a Location object which is not a primitive, and so it will trigger exhaustive deps if it is being used by way of a reference inside the component render function (assigned to a variable), since it could theoretically be a different object reference on subsequent renders.

Since the linter can't necessarily tell if the reference has changed out from under it on subsequent renders due to the fact that it could be mutably changed, it marks it as a necessary dep.

Re:React: You Might Not Need an Effect by kajaktum on Thursday March 23, 2023 @09:02AM (#35274061)
This seems obvious to me? Your lambda captures an outside object that will change with each render pass?
Re:React: You Might Not Need an Effect by cush on Thursday March 23, 2023 @10:11AM (#35275103)
I recommend you read the article again. Just because window.location changes outside scope doesn't mean that React would update the component when window.location changes just because you put it in a dependency array.

This is because props or state didn't change and the parent didn't rerender.

UseEffect dependencies aren't observables. You'd need to wire up an event listener on unload, hashChange, etc

https://stackoverflow.com/questions/58442168/why-useeffect-d...