Error: useState and useMemo is called conditionally.ct Hooks must be called in the exact same order
Unanswered
Jenn posted this in #help-forum

JennOP
const OrderComponent: React.FC<OrderComponentProps> = ({
error,
waterTypes,
refillingStation,
}) => {
if (error) {
return <div>Error: {error.message}</div>;
}
if (!waterTypes || !refillingStation) {
return <div>Loading...</div>;
}
const [user, setUser] = useState<User>({
firstName: '',
//
})
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setUser((prevUser) => ({
...prevUser,
[name]: value,
}));
};
const [cart, setCart] = useState< WaterTypeQty[]>([])
const total = useMemo<number>(() => {
const calculateTotal = () => {
return cart.reduce((total, item) => total + item.price * item.quantity, 0);
};
return calculateTotal();
}, [cart])
1 Reply

Toyger
hooks should be before any conditional return, it described here https://legacy.reactjs.org/docs/hooks-rules.html
if order of hook execution changes between renders it break logic.
by early return you break order, so you need put your hooks run before, below is corrected code.
either you make your conditions on level higher where you passing your props, and check them before render this component.
if order of hook execution changes between renders it break logic.
by early return you break order, so you need put your hooks run before, below is corrected code.
either you make your conditions on level higher where you passing your props, and check them before render this component.
const OrderComponent: React.FC<OrderComponentProps> = ({
error,
waterTypes,
refillingStation,
}) => {
const [user, setUser] = useState<User>({
firstName: '',
//
})
const [cart, setCart] = useState< WaterTypeQty[]>([])
const total = useMemo<number>(() => {
const calculateTotal = () => {
return cart.reduce((total, item) => total + item.price * item.quantity, 0);
};
return calculateTotal();
}, [cart])
if (error) {
return <div>Error: {error.message}</div>;
}
if (!waterTypes || !refillingStation) {
return <div>Loading...</div>;
}
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setUser((prevUser) => ({
...prevUser,
[name]: value,
}));
};