Soy bastante nuevo en React. Estoy tratando de crear un controlador de ruta privado con la nueva versión de react-router-dom v6, por lo que necesito verificar si el usuario está autenticado o no para saber si devuelve la ruta protegida o redirigir al usuario al inicio de sesión ruta.
import { Navigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { isLogged } from '../helpers/isLogged'; export const PrivateRoute = async ({children}) => { // Check if the user is authenticated const userData = useSelector( store => store.user.object); const logged = await isLogged(userData); return logged ? children : <Navigate to="/login" />; }El problema es que recibo algunos errores debido a esto, pero principalmente el objeto promete uno.
¿Que esta pasando? ¡Gracias por adelantado!
No puede declarar un componente asíncrono, porque una función asíncrona devuelve una Promesa, por lo que cuando la use no será un componente sino un objeto Promesa.
Si necesita realizar una operación asíncrona, debe usar useEffect Hook:
export const PrivateRoute = ({ children }) => { const [logged, setlLogged] = useState(false); useEffect(() => { isLogged(userData).then((res) => { setIsUserLogged(res); }); }, []); // Check if the user is authenticated const userData = useSelector((store) => store.user.object); return logged ? children : <Navigate to="/login" />; };También puedes usar async/await dentro del gancho useEffect pero es un poco más complicado, te dejaré profundizar en eso
Entonces, gracias a que Hugo pudo resolverlo.
También usé esto: React Hook Warnings para la función asíncrona en useEffect: la función useEffect debe devolver una función de limpieza o nada
En pocas palabras, la solución estaba usando useEffect y usando una función asíncrona interna y, mientras esto se ejecuta, opcionalmente podría representar cualquier otra cosa, en mi caso "esperando...".
import { useEffect, useState } from 'react'; import { Navigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { isLogged } from '../helpers/isLogged'; export const PrivateRoute = ({children}) => { const userData = useSelector((store) => store.user.object); const [logged, setLogged] = useState(false); const [checking, setChecking] = useState(true); useEffect(() => { const checkAuth = async () => { // Check if the user is authenticated isLogged(userData).then((res) => { setLogged(res); // sets checking variable in false so the component can be rendered. setChecking(false); }); } checkAuth(); }, [userData]); if(checking){ // Renders 'wait' until isLogged is resolved with the data. return (<h1>Wait...</h1>); } return logged ? children : <Navigate to="/login" /> }