Reputation: 4803
The following (albeit contrived) component violates react-hooks/rules-of-hooks (via eslint)
function Apple(props){
const {seeds} = props;
if(!seeds){
return null;
}
const [bitesTaken, setBitesTaken] = useState(0);
return <div>{bitesTaken}</div>
}
with the following error
React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?
I understand that hooks need to be called in the same order, but this kind of conditional rendering (so long as no hooks are invoked before the return, does not prevent the hooks from being called in the same order. I think the eslint rule is too strict, but maybe there's a better way.
What is the best way to conditionally render a component which uses hooks?
Upvotes: 4
Views: 9075
Reputation: 2656
Another option is to split the component.
import React,{useState} from 'react';
const Apple = (props) => {
const {seeds} = props;
return !!seeds && <AppleWithSeeds />;
};
const AppleWithSeeds =(props) => {
const [bitesTaken] = useState(0);
return <div>{bitesTaken}</div>
};
export default Apple;
Advantage of this method is that your components stay small and logical.
And in your case you might have something more than '0' in the useState initializer which you don't want unnecessary at the top before the condition.
Upvotes: 5
Reputation: 2964
You can't conditionally use hooks, so move the hook above the condition.
function Apple(props){
const {seeds} = props;
const [bitesTaken, setBitesTaken] = useState(0);
if(!seeds){
return null;
}
return <div>{bitesTaken}</div>
}
You can also simplify the rendering like this:
function Apple(props) {
const { seeds } = props
const [bitesTaken, setBitesTaken] = useState(0)
return !!seeds && <div>{bitesTaken}</div>
}
If seeds
is falsey, then false
will be returned (which renders as nothing), otherwise, the div
will be returned.
I've added the double exclamation point to seeds
to turn it into a boolean, because if seeds
is undefined
then nothing is returned from render and React throws an error.
Upvotes: 4