React hook - предупреждение об отсутствии зависимостей в useEffect - PullRequest
1 голос
/ 01 августа 2020

Я не уверен, является ли это допустимым предупреждением при использовании useEffect вокруг массива зависимостей, похоже, что всякий раз, когда переменная, метод или диспетчер внутри useEffect выдают предупреждение, что React Hook useEffect имеет недостающие зависимости : «активный», «получатель» и «отправка». Либо включите их, либо удалите массив зависимостей из следующего примера, если я просто оставлю его как пустой массив для выполнения функций componentDidMount

useEffect(() => {
   setActive(active);   
   await retrieveUser(param1, param2);
   dispatch(someAction);
}, []).        // warning: React Hook useEffect has missing dependencies: 'active', 'retrieveUser', 'param1', 'param2', and 'dispatch'. Either include them or remove the dependency array, but here I just want to perform componentDidMount concept so my dependency list has to be empty

или

useEffect(() => {
   await retrieveUser(param1, param2);
   dispatch(someAction);
}, [userId]).   // warning: React Hook useEffect has missing dependencies: 'retrieveUser', 'param1', 'param2', and 'dispatch'. Either include them or remove the dependency array

Are эти действительные предупреждения? Особенно то, что я просто хочу отслеживать поле данных c, какой смысл добавлять всю внутреннюю отправку или метод в массив зависимостей, если я не могу добавить что-либо в список зависимостей (для componentDidMOunt) или я просто хочу отслеживать userId, а не param1, param2 и т. Д. c

Ответы [ 2 ]

2 голосов
/ 01 августа 2020

React выдает это предупреждение, потому что вы используете часть состояния или свойств вашего компонента в useEffect, но сказали ему не запускать обратный вызов useEffect при изменении этого состояния / свойств. React предполагает, что вы захотите запускать этот useEffect() всякий раз, когда указанные состояния изменяются, поэтому он выдает вам предупреждение. Если бы вы ссылались только на переменные вне состояния или свойств, вы бы не получили это предупреждение. См. Ниже информацию об условном запуске useEffect.

Поскольку ваша цель - только запускать useEffect только иногда вам, вероятно, потребуется реструктурировать свой компонент, чтобы разные данные находились в состоянии или вне его. Трудно рекомендовать более конкретные c решения, не зная больше о компоненте; но хорошая цель состоит в том, чтобы состояние, которое вы используете в useEffect, совпадало с изменениями, которые вы хотите инициировать повторной визуализацией.

Могут быть другие проблемы с состоянием в вашем компоненте. Например, я заметил, что вы звоните по номеру setActive(active);. Если active является частью состояния компонента, это означает, что вы устанавливаете active для самого себя. В этом нет необходимости. (предполагается, что вы следуете типичным шаблонам именования и, вероятно, имеете строку в верхней части компонента, например:

const [active, setActive] = useState(initialValue);

Условно выполняется useEffect

Когда вы предоставляете второй аргумент для useEffect(), это ограничивает ситуации, когда useEffect запускает функцию обратного вызова при повторных рендерах. Это сделано из соображений производительности, как описано в React docs .

В первом useEffect, где вы предоставляете пустой массив, вы указываете React запускать только эти действия (setActive(active) ... et c.), когда компонент монтируется и отключается.

Во втором useEffect, где вы предоставляете массив с userId, вы указываете React запускать обратный вызов только при монтировании, unmount и всякий раз, когда userId изменяется.

React выдает вам это предупреждение, потому что знает, что не будет запускать useEffect, если active ... et c или другие значения изменятся. Это может привести к тому, что разные части вашего компонента будут ссылаться на разные состояния. Например, одна часть вашего компонента может использовать userId = 1, а другая часть - userId = 2. React разработан для работы не так.

0 голосов
/ 01 августа 2020

Создайте ловушку, которая выполняется только один раз:

const useEffectOnce = effect => {
    useEffect(effect, []);
};

используйте эту ловушку внутри вашего компонента

useEffectOnce(() => {
    const request = async () => {
        const result = await retrieveSum(param1, param2);
        setResult(result);
    };

    request();
});

Теперь, даже если ваши props (param1, param2) изменятся, эффект вызывается только один раз. Будьте очень осторожны при этом, компонент, вероятно, содержит ошибки, если только ваши первоначальные свойства не являются действительно особенными. Я не понимаю, чем это отличается от отключения правила с помощью

// eslint-disable-next-line react-hooks/exhaustive-deps

Demo: https://codesandbox.io/s/trusting-satoshi-fngrw?file= / src / App. js

...