#reactjs #react-hooks #eslint
Вопрос:
export const useMyCustomHook = () => {
const uiLoad = useUiLoad(false);
useEffect(() => {
// ...
}, [...]);
}
uiLoad
является пользовательским крючком (как, очевидно, useMyCustomHook
и есть ). Это прекрасно работает, если я не добавляю uiLoad
в массив useEffect
зависимостей. Если я включу его, он бесконечно перерисовывается.
Вот мой код для uiLoad
крючка:
const baseDispatch = {
type: SET_LOADING
}
export const useUiLoad = (initial: boolean = false) => {
const dispatch = useDispatch<Dispatch<UIAction>>();
const loaded = useRef(false);
useEffect(() => {
if (initial amp;amp; !loaded.current) {
console.log('Called');
dispatch({
type: SET_LOADING,
loadbarShowing: true
});
loaded.current= true;
}
}, [dispatch, initial])
return (loading: boolean) => {
const data: UIAction = {
...baseDispatch,
loadbarShowing: loading
}
dispatch(data);
}
}
Насколько я знаю, крючки не меняются при повторной визуализации. Итак, вопросы таковы:
- Почему нагрузка меняется при каждом повторном запуске? Используя
useWhatChanged
инструмент отладчика, я могу обнаружить, что он действительно меняется каждый раз, когда компонент повторно визуализируется. Разве крючки не остаются одинаковыми при каждом рендеринге? Или это не относится к пользовательским крючкам? - Является ли единственным решением здесь подавление предупреждения с помощью
// eslint-disable-next-line
?
Комментарии:
1.
useUiLoad
возвращает новую функцию каждый раз, когда она вызывается, попробуйте запомнить возвращенную функцию вuseCallback
крючке.2. @DrewReese Это должно было быть очевидно для меня, и это сработало. Опубликуйте это в качестве ответа
Ответ №1:
Крючки вызываются каждый раз при визуализации компонента. useUiLoad
Возвращает новую функцию каждый раз, когда она вызывается. Вы можете вернуть функцию с памятью, чтобы она была стабильной ссылкой.
export const useUiLoad = (initial: boolean = false) => {
const dispatch = useDispatch<Dispatch<UIAction>>();
const loaded = useRef(false);
useEffect(() => {
if (initial amp;amp; !loaded.current) {
console.log('Called');
dispatch({
type: SET_LOADING,
loadbarShowing: true
});
loaded.current= true;
}
}, [dispatch, initial]);
return useCallback((loading: boolean) => {
const data: UIAction = {
...baseDispatch,
loadbarShowing: loading
}
dispatch(data);
}, [dispatch]); // <-- add any other dependencies if necessary
}