React не позволяет вам сделать ранний возврат до других хуков.Если компонент выполняет меньше хуков, чем предыдущий рендер, вы получите следующую ошибку:
Инвариантное нарушение: рендеринг меньше хуков, чем ожидалось.Это может быть вызвано случайным оператором раннего возврата.
React не может определить разницу между ранним возвратом и условным вызовом ловушки.Например, если у вас есть 3 вызова на useState
, и вы иногда возвращаетесь после второго, React не может определить, вернулись ли вы после второго useState
вызова или если вы поставили условие вокруг первого или второго useState
call, поэтому он не может достоверно знать, возвращает ли он правильное состояние для двух useState
вызовов, которые произвел .
Вот пример, который вы можете использовать, чтобы увидетьэта ошибка в действии (дважды нажмите кнопку «Инкрементное состояние 1», чтобы получить ошибку):
import React from "react";
import ReactDOM from "react-dom";
function App() {
const [state1, setState1] = React.useState(1);
if (state1 === 3) {
return <div>State 1 is 3</div>;
}
const [state2, setState2] = React.useState(2);
return (
<div className="App">
<div>State 1: {state1}</div>
<div>State 2: {state2}</div>
<button onClick={() => setState1(state1 + 1)}>Increment State 1</button>
<button onClick={() => setState2(state2 + 1)}>Increment State 2</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
![Edit Early return with hooks](https://codesandbox.io/static/img/play-codesandbox.svg)
Альтернативный подход, который я рекомендовал бысостоит в том, чтобы отделить часть после досрочного возврата в свой собственный компонент.Все, что нужно части после раннего возврата, передается новому компоненту в качестве реквизита.
В моем примере это может выглядеть следующим образом:
import React from "react";
import ReactDOM from "react-dom";
const AfterEarlyReturn = ({ state1, setState1 }) => {
const [state2, setState2] = React.useState(2);
return (
<div className="App">
<div>State 1: {state1}</div>
<div>State 2: {state2}</div>
<button onClick={() => setState1(state1 + 1)}>Increment State 1</button>
<button onClick={() => setState2(state2 + 1)}>Increment State 2</button>
</div>
);
};
function App() {
const [state1, setState1] = React.useState(1);
if (state1 === 3) {
return <div>State 1 is 3</div>;
}
return <AfterEarlyReturn state1={state1} setState1={setState1} />;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
![Edit Early return with hooks](https://codesandbox.io/static/img/play-codesandbox.svg)