Доступ к контексту из useEffect

У меня есть контекст, который используется для отображения полного счетчика страниц, пока мое приложение выполняет длительные задачи.

Когда я пытаюсь получить к нему доступ внутри useEffect, я получаю сообщение react-hooks/exhaustive-deps ESLint. Например, следующий код, хотя и работает как положено, утверждает, что busyIndicator — это отсутствующая зависимость:

const busyIndicator = useContext(GlobalBusyIndicatorContext);

useEffect(() => {
    busyIndicator.show('Please wait...');
}, []);

В статье Этот предлагается обернуть функцию useCallback, которая может выглядеть следующим образом:

const busyIndicator = useContext(GlobalBusyIndicatorContext);
const showBusyIndicator = useCallback(() => busyIndicator.show('Please wait...'), []);

useEffect(() => {
    showBusyIndicator();
}, [showBusyIndicator]);

Хотя это работает, проблема переместилась в строку useCallback, которая теперь жалуется на отсутствующую зависимость.

Можно ли игнорировать сообщение ESLint в этом сценарии или я что-то упустил?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
18
0
20 884
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если ваш busyIndicator не изменился в течение жизни компонента, вы можете просто добавить его как зависимость к useEffect:

const busyIndicator = useContext(GlobalBusyIndicatorContext);

useEffect(() => {
    busyIndicator.show('Please wait...');
}, [busyIndicator]);

Если busyIndicator можно изменить и вы не хотите видеть ошибку, вы можете использовать useRef хук:

const busyIndicator = useRef(useContext(GlobalBusyIndicatorContext));

useEffect(() => {
    busyIndicator.current.show('Please wait...');
}, []);

The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class. read more

Спасибо, я использовал useRef и useContext независимо, но мне никогда не приходило в голову, что их можно использовать вместе.

Newm 21.05.2019 17:54

@Newm Трюк с useRef был действительно отличным и решил проблему для меня ... спасибо! Два года спустя я спрашиваю, достаточно ли у вас понимания, чтобы объяснить, ПОЧЕМУ это решает проблему? Очень любопытно понять, что это делает по-другому.

ogg130 05.02.2021 03:39

Только что нашел этот трюк, и он сработал. @ ogg130 Причина, по которой это работает, заключается в том, что useRef создает ссылку, которая сохраняется в течение всего срока службы компонента — из документации reactjs.org/docs/hooks-reference.html#useref «useRef возвращает изменяемый объект ref, свойство .current которого инициализируется переданным аргументом (initialValue). Возвращаемый объект будет сохраняться в течение всего срока службы компонента». Обычно вы видите, что он используется со ссылками на элементы, но вы можете использовать его для многих вещей.

Jarrod McGuire 15.04.2021 00:17

Не нужно обертывать ваш useContext в хук useRef. вы можете обновить свои контекстные данные, просто позвоните в useEffect Brackets так.

const comingData = useContext(taskData);

useEffect(() => {
console.info("Hi useEffect");
}},[comingData]); //context data is updating here before render the component

В этом примере компонент не будет отображаться. Если у вас есть что-то в useEffect, что вызовет повторную визуализацию (например, отправка в хранилище с помощью селектора, обновление состояния), повторная визуализация компонента создаст новую ссылку на useContext, что приведет к повторному запуску useEffect и создаст бесконечный петля. По крайней мере, так случилось со мной. Использование useRef решило это красиво

Jarrod McGuire 15.04.2021 00:12

console.info будет срабатывать каждый раз, когда какое-либо событие будет обновлять контекст, в моем случае это добавило мне +800 МБ памяти за несколько секунд.

Aziz 26.06.2021 02:42

Другие вопросы по теме