Actualmente estoy tratando de hacer que una ruta protegida funcione en reaccionar. Deseo que el result devuelva un valor booleano en lugar de una promesa sin cambiar ProtectedRoute a async :
import React from "react"; import { Redirect, Route } from "react-router-dom"; import { CheckToken } from "./RequestAction" function ProtectedRoute({ component: Component, ...restOfProps }) { const result = (async () => { const res = await CheckToken() return res; })() console.log(result); //log-> Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: false return ( <Route {...restOfProps} render={(props) => result ? <Component {...props} /> : <Redirect to="/login/" /> } /> ); } export default ProtectedRoute; Esta es la función CheckToken :
import axios from "axios"; async function CheckToken() { let result = null; await axios .get(`http://localhost:5000/protected`, {"withCredentials": true} ) .then((res) => { console.log("res.data.status:",res.data) if (res.data.status === "success") { result = true } }) .catch((err) => { result = false }); console.log("result:",result); return result }const useToken = () => { const [token, setToken] = useState(null); useEffect(() => { const f = async () => { const res = await CheckToken(); //TODO: add check login; setToken(res); }; f(); }) return token; } function ProtectedRoute({ component: Component, ...restOfProps }) { const token = useToken(); return ( <Route {...restOfProps} render={(props) => token ? <Component {...props} /> : <Redirect to="/login/" /> } /> ); }El cuerpo del componente de función no puede ser asíncrono.
De acuerdo, entonces en su componente de función está tratando de contactar a un servidor por procesamiento, y está diciendo que desea capturar el resultado en un valor booleano, que luego se pasa a su componente de ruta secundario
En primer lugar, las solicitudes de red se consideran efectos, generalmente provocados por un cambio en los accesorios de su componente. le gustaría manejar el comportamiento de la red de forma asíncrona, ya que de lo contrario bloquearía la representación del componente, que es algo que React no permite. Además, probablemente solo desee verificar el token en circunstancias específicas, según sus accesorios.
Todavía puede procesar su componente secundario Route una vez que su solicitud de red se haya resuelto, pero hasta entonces, habrá un estado intermedio que su componente deberá manejar. Cómo lo hace depende de usted, pero probablemente no debería mostrar un enlace hasta que tenga la información del resultado.
Introduciría un poco de estado en un gancho personalizado, y solo haría que su componente devolviera algún estado intermedio hasta que obtenga un resultado/error.
También devolvería un token, puede usar nulo para indicar que la solicitud de red no se ha completado y una cadena vacía si no se ha recuperado.
const useToken = () => { const [state, setState] = useState(null) useEffect(() => { //TODO: you would also want to catch errors CheckToken().then(setState) }) return state } function ProtectedRoute({ component: Component, ...restOfProps }) { const token = useToken() if (token === null) { return <Spinner/> // something that indicates you are waiting } return ( <Route {...restOfProps} render={(props) => token ? <Component {...props} /> : <Redirect to="/login/" /> } />) } }