React, ESLint: eslint-plugin-react-hooks показывает неверную "отсутствующую зависимость"

Предположим, вы используете React и пишете собственный хук. useSomething которая возвращает одно и то же каждый раз, когда вызывается для одного и того же компонента.

const something = useSomething()

// useSomething() at time X  === useSomething() at time Y

Если вы сейчас используете это something значение внутри useEffect(() => ...) и ты не проходишь something как зависимость от массива второго аргумента useEffect тогда линтер предупредит вас:

У React Hook useEffect отсутствует зависимость: "что-то". Либо включите его, либо удалите массив зависимостей. (реагировать-крючки / исчерпывающие-глубины)

Конечно, ESLint не может знать, что something всегда будет оставаться идентичным (для каждого компонента), но добавление неизменных вещей, таких как something в массив зависимостей useEffectкаждый раз их использование действительно раздражает. Просто деактивируйтеreact-hooks/exhaustive-deps также не кажется хорошим решением (ни с использованием // eslint-disable-next-line react-hooks/exhaustive-deps).

Есть ли лучшее решение, чем без надобности добавлять подобные вещи в массив зависимостей useEffect просто чтобы ЛИНТЕР был счастлив?

Пожалуйста, найдите здесь простую демонстрацию:https://codesandbox.io/s/sad-kowalevski-yfxcn [Изменить: имейте в виду, что проблема заключается в общем шаблоне, описанном выше, а не в этой глупой маленькой демонстрации - цель этого демо просто показывает предупреждение ESLint, ничего больше]

[Edit] Пожалуйста, найдите дополнительную демонстрацию здесь:https://codesandbox.io/s/vibrant-tree-0cyn1

2 ответа

Решение

Вот

https://github.com/facebook/react/issues/14920

например, вы можете прочитать это:

Если он действительно постоянный, то указание его в deps не повредит. Например, в случае, когда функция setState внутри настраиваемого хука возвращается вашему компоненту, а затем вы вызываете ее из эффекта. Правило lint недостаточно умен, чтобы понять подобное косвенное обращение. Но с другой стороны, любой может обернуть этот обратный вызов позже, прежде чем вернуться, и, возможно, сослаться на другую опору или состояние внутри него. Тогда это не будет постоянным! И если вам не удастся обработать эти изменения, у вас будут неприятные устаревшие ошибки свойств / состояний. Так что указать это по умолчанию лучше.

Так что, возможно, просто добавив эти никогда не меняющиеся значения в массив зависимостей useEffectеще может быть лучшим решением. Тем не менее я надеялся, что будет что-то вроде возможности конфигурации ESLint react-hooks для определения списка имен хуков, возвращаемые значения которых следует рассматривать как статические.

Пример немного надуманный, но я подозреваю, что вы можете захотеть создать новый useEffect блок без этой зависимости.

Если магазин не меняется, я бы спросил, почему вы хотите, чтобы это время было консольным. Если вы хотите регистрировать его только при изменении, вы должны добавитьsomeStoreв ваш массив зависимостей. На самом деле это зависит от того, чего вы пытаетесь достичь, и от того, что вас беспокоит.

Я бы сказал, что если someStoreиспользуются как часть любой логики обрабатываются в этом эффекте то он делает принадлежит в массиве зависимостей.

Вы также можете переместить const something = useSomething()в свой эффект и извлеките его как пользовательскую ссылку на крючок

useEffect(() => {
    console.log("Current state (may change)", someState);

  }, [someState]); 

useEffect(() => {
    console.log("Current store (will never change)", someStore);
  }); 
Другие вопросы по тегам