#reactjs #react-hooks #use-effect
Вопрос:
Я ищу рекомендации о том, как решить следующую проблему:
У меня есть компонент A, который имеет два состояния, состояние 1 и состояние 2.
Если я хочу запускать эффект только при изменении состояния 1, но в обратном вызове useEffect я использую значение состояния 2, как я могу решить проблему с предупреждением о зависимостях массива eslint react hooks ?
Экс.
function A() { const [state1, setState1] = useState(0); const [state2, setState2] = useState(0); useEffect(() =gt; { const a = state1 state2; // do some async logic using a }, [state1]); //Here eslint react hooks rule requests adding state2 to the dependency array! return lt;divgt; some text lt;/divgt; }
Ответ №1:
Обычно распространенным методом было бы отключить правило компоновки специально для этой строки.
function A() { const [state1, setState1] = useState(0); const [state2, setState2] = useState(0); useEffect(() =gt; { // do some async logic using a const a = state1 state2; // eslint-disable-next-line react-hooks/exhaustive-deps }, [state1]); return lt;divgt; some text lt;/divgt;; }
Но недостатком здесь является то, что он может маскировать проблемы с зависимостями, если зависимости действительно изменяются, и вы забываете обновить массив зависимостей.
Вы можете использовать ссылку React и дополнительный useEffect
крюк для кэширования текущего state2
значения и ссылаться на это в другом useEffect
обратном вызове.
function A() { const [state1, setState1] = useState(0); const [state2, setState2] = useState(0); const state2Ref = useRef(state2); useEffect(() =gt; { state2Ref.current = state2; }, [state2]); useEffect(() =gt; { // do some async logic using a const a = state1 state2Ref.current; }, [state1]); return ( ... ); }
function A() { const [state1, setState1] = React.useState(0); const [state2, setState2] = React.useState(0); const state2Ref = React.useRef(state2); React.useEffect(() =gt; { state2Ref.current = state2; }, [state2]); React.useEffect(() =gt; { // do some async logic using a const a = state1 state2Ref.current; console.log("effect called", a); }, [state1]); return ( lt;divgt; some text lt;divgt; lt;button type="button" onClick={() =gt; setState1((c) =gt; c 1)}gt; Update State 1 lt;/buttongt; lt;button type="button" onClick={() =gt; setState2((c) =gt; c 1)}gt; Update State 2 lt;/buttongt; lt;/divgt; lt;/divgt; ); } const rootElement = document.getElementById("root"); ReactDOM.render( lt;A /gt;, rootElement );
lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"gt;lt;/scriptgt; lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"gt;lt;/scriptgt; lt;div id="root" /gt;
Ответ №2:
Вам нужно добавить // eslint-disable-next-line react-hooks/exhaustive-deps
в свой пользовательский эффект вот так:
function A() { const [state1, setState1] = useState(0); const [state2, setState2] = useState(0); useEffect(() =gt; { const a = state1 state2; // do some async logic using a // eslint-disable-next-line react-hooks/exhaustive-deps }, [state1]); //Here eslint react hooks rule requests adding state2 to the dependency array! return lt;divgt; some text lt;/divgt; }
Комментарии:
1. Спасибо @Luccin, но я ищу более продвинутый способ, не отключая это правило. Например, я подумал о создании новой ссылки, которая содержит обновленное значение state2…