React se queja del código a continuación, diciendo que useEffect se llama condicionalmente:
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))Y eso me devuelve el error:
React Hook "useEffect" se llama condicionalmente. Los React Hooks deben llamarse exactamente en el mismo orden en cada renderizado de componentes.
¿Alguien sabe cuál es el problema aquí?
Su código, después de una instrucción if que contiene return , es equivalente a una rama else :
if(!firebase.getCurrentUsername()) { ... return null } else { useEffect(...) ... } Lo que significa que se ejecuta condicionalmente (solo cuando la return NO se ejecuta).
Arreglar:
useEffect(() => { if(firebase.getCurrentUsername()) { firebase.getCurrentUserQuote().then(setQuote) } }, [firebase.getCurrentUsername(), firebase.getCurrentUserQuote()]) if(!firebase.getCurrentUsername()) { ... return null }No llame a Hooks dentro de bucles, condiciones o funciones anidadas. En su lugar, siempre use Hooks en el nivel superior de su función React. Puede seguir la documentación aquí .
No pude encontrar el caso de uso en el código anterior. Si necesita que el efecto se ejecute cuando cambie el valor de retorno de firebase.getCurrentUsername() , es posible que desee usarlo fuera de la condición if como:
useEffect(() => { firebase.getCurrentUserQuote().then(setQuote) }, [firebase.getCurrentUsername()]);Tuve un problema similar con el mismo mensaje de error, donde el orden de las declaraciones de variables era la fuente del error:
if (loading) return <>loading...</>; if (error) return <>Error! {error.message}</>; const [reload, setReload] = useState(false); const [reload, setReload] = useState(false); if (loading) return <>loading...</>; if (error) return <>Error! {error.message}</>;El gancho debe crearse antes de los posibles bloques de devolución condicional.