React is complaining about code below, saying it useEffect is being called conditionally:
import React, { useEffect, useState } from 'react' import VerifiedUserOutlined from '@material-ui/icons/VerifiedUserOutlined' import withStyles from '@material-ui/core/styles/withStyles' import firebase from '../firebase' import { withRouter } from 'react-router-dom' function Dashboard(props) { const { classes } = props const [quote, setQuote] = useState('') if(!firebase.getCurrentUsername()) { // not logged in alert('Please login first') props.history.replace('/login') return null } useEffect(() => { firebase.getCurrentUserQuote().then(setQuote) }) return ( <main> // some code here </main> ) async function logout() { await firebase.logout() props.history.push('/') } } export default withRouter(withStyles(styles)(Dashboard))
And that returns me the error:
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
Does anyone happen to know what the problem here is?
The error "React hook 'useEffect' is called conditionally" occurs when we use the useEffect hook conditionally or after a condition that may return a value. To solve the error, move all React hooks above any conditionals that may return a value.
This is not allowed because the number of hooks and the order of hook calls have to be the same on re-renders of our function components. To solve the error, we have to move the useState call to the top level and not conditionally call the hook.
Don't call Hooks inside loops, conditions, or nested functions. Instead, 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.
useEffect(() => { // Side Effect }, []); In this case, the side effect runs only once after the initial render of the component.
Your code, after an if
statement that contains return
, is equivalent to an else
branch:
if(!firebase.getCurrentUsername()) { ... return null } else { useEffect(...) ... }
Which means that it's executed conditionally (only when the return
is NOT executed).
To fix:
useEffect(() => { if(firebase.getCurrentUsername()) { firebase.getCurrentUserQuote().then(setQuote) } }, [firebase.getCurrentUsername(), firebase.getCurrentUserQuote()]) if(!firebase.getCurrentUsername()) { ... return null }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With