Правила хуков требуют, чтобы при каждом рендере вызывались одинаковые хуки и в одинаковом порядке.И есть объяснение того, что пойдет не так, если вы нарушите это правило.Например, этот код:
function App() {
console.log('render');
const [flag, setFlag] = useState(true);
const [first] = useState('first');
console.log('first is', first);
if (flag) {
const [second] = useState('second');
console.log('second is', second);
}
const [third] = useState('third');
console.log('third is', third);
useEffect(() => setFlag(false), []);
return null;
}
Вывод на консоль
render
first is first
second is second
third is third
render
first is first
third is second
И вызывает предупреждение или ошибку.
Но как насчет условий, которые не меняются во времяЖизненный цикл элемента?
const DEBUG = true;
function TestConst() {
if (DEBUG) {
useEffect(() => console.log('rendered'));
}
return <span>test</span>;
}
Этот код на самом деле не нарушает правила и, кажется, работает нормально.Но он все еще вызывает предупреждение eslint.
Более того, представляется возможным написать аналогичный код на основе реквизита:
function TestState({id, debug}) {
const [isDebug] = useState(debug);
if (isDebug) {
useEffect(() => console.log('rendered', id));
}
return <span>{id}</span>;
}
function App() {
const [counter, setCounter] = useState(0);
useEffect(() => setCounter(1), []);
return (
<div>
<TestState id="1" debug={false}/>
<TestState id="2" debug={true}/>
</div>
);
}
Этот код работает как задумано.
Итакбезопасно ли вызывать перехватчики внутри условия, когда я уверен, что оно не изменится?Можно ли изменить правило eslint для распознавания таких ситуаций?
Вопрос скорее в реальных требованиях, а не в способе реализации подобного поведения.Насколько я понимаю, важно
гарантировать, что хуки вызываются в одном и том же порядке каждый раз при рендеринге компонента.Это то, что позволяет React правильно сохранять состояние хуков между несколькими вызовами useState и useEffect
И есть место для исключений из этого правила: «Не вызывайте хуки внутри циклов, условий или вложенных элементов».функции».