2

Suppose I wanted to create a React Hook that's like useEffect, but it only runs when all the dependencies are non-null. It looks like this:

const useNonNullEffect = (callback: () => void, deps: any[]) => useEffect(() => {
    if(deps.every(dep => dep !== null)) callback()
}, deps)

However, this fails to pass the "strict dependency" linter:

  • It sees callback as an undeclared dependency.
  • I can't parse deps, since it's not an array literal.

Is there some way to create hooks like this, where I take a set of dependencies from the user and forward them to the "real" hook?

(My actual use case is more complicated, this is just a simple expression of the problem for Stack Overflow purposes)

2
  • There's nothing technically wrong with your code, this is just an intentional limitation of the static analysis performed by the exhaustive-deps lint rule. To my knowledge all cases where you try to dynamically pass dependencies will throw this warning, including using spread syntax, because dynamic and non-liiteral arrays are not exhaustive. If you know what you're doing, however you can add // eslint-disable-next-line react-hooks/exhaustive-deps right before the line where deps is and the warning should go away. Commented May 21, 2019 at 0:47
  • Yeah; my question is if there are any more semantic solutions– that is, if there's a way to make the linter aware of the relationship between callback and deps Commented May 21, 2019 at 1:02

1 Answer 1

2

I don't think the linter complains about the deps or the callback if you don't declare your useEffect callback inline like so:

const useNonNullEffect = (callback: () => void, deps: any[]) => {
  const fn = () => {
    if(deps.some(dep => dep === null)){
      return
    }
    return callback()
  }
  useEffect(fn, deps)
}

Not sure if it's intentional or if the behavior might change in the future, but for now if you check the problems tab in this codesandbox there should be 0 linting problems reported.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.