Posted on under React by Owen Conti.
In React, hooks must be called during render, and they must be called unconditionally and in the same order every render.
This means if you have a conditional
if
statement in your render logic, hooks cannot be within the conditional branch.
1function MyComponent(props) { 2 if (props.id) { 3 // BAD! Hooks cannot be used inside a conditional statement 4 useEffect(() => { 5 axios.get(`/api/data?id=${props.id}`); 6 }); 7 } 8 9 // ...render the component10}
It also means that you cannot use hooks after your conditional statement, if your conditional statement returns early, ie:
1function MyComponent(props) { 2 if (props.loading) { 3 return <Loading />; 4 } 5 6 const [state, setState] = useState(null) 7 8 return ( 9 <div>My component markup here...</div>10 );11}
In this case, if the
loading
prop is true, our component will return early resulting in the hook sometimes being called instead of always being called.
Okay, so what if I need to conditionally call a hook?
You can move the conditional logic inside of the hook:
1function MyComponent(props) {2 useEffect(() => {3 if (props.id) {4 axios.get(`/api/data?id=${props.id}`);5 }6 }, [props.id]);7 8 // ...render the component9}
The key is to make sure that all hooks you use are called every render, because React is tracking the hook calls (and their order!) behind the scenes.
Hopefully you found this article useful! If you did, share it on X!
Found an issue with the article? Submit your edits against the repository.