From React documentation:
Always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the
same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple
useState
and
useEffect
calls.
React is relying on the order of the Hook calls to know which local state matches which Hook call. That is why it’s important that the Hooks are
not called inside loops, conditions, or nested functions.
Also this rule ensures that the Hooks are called only from React function components or custom Hooks so that the stateful logic of a component is
clearly visible from its source code.
Noncompliant Code Example
function Profile() {
const [ordersCount, setOrdersCount] = useState(0);
if (ordersCount !== 0) {
useEffect(function() { // Noncompliant, this Hook is called conditionally
localStorage.setItem('ordersData', ordersCount);
});
}
return <div>{ getName() }</div>
}
function getName() {
const [name] = useState('John'); // Noncompliant, this Hook is called from simple JavaScript function
return name;
}
Compliant Solution
function Profile() {
const [ordersCount, setOrdersCount] = useState(0);
useEffect(function() {
if (ordersCount !== 0) {
localStorage.setItem('ordersData', ordersCount);
}
});
const [name] = useState('John');
return <div>{ name }</div>
}
See