Hola, estoy tratando de crear una aplicación de reacción simple con una función de navegación. El tema principal es que tengo 3 componentes, App, Test y AppShell. El componente de la aplicación es el componente predeterminado (inicial). Y lo que quiero es que cada vez que el usuario vaya al componente de la aplicación, mi aplicación se redirigirá al componente de prueba .
El problema al que me enfrento es que mi redirección solo funciona cuando cargo la aplicación por primera vez, después de eso, mi redirección no funciona.
¡Estoy compartiendo mi código de tres componentes a continuación junto con la página de índice!
Página de inicio
import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; ReactDOM.render( <Router> <Routes> <Route path='/' element={<App />} /> <Route path='/test' element={<Test />} /> </Routes> </Router>, document.getElementById('root') ); function Test() { return <h1>Test Me</h1>; } reportWebVitals();Componente de la aplicación
import "./App.css"; import AppShell from "./components/core/appShell"; import { useNavigate } from 'react-router-dom'; export default function App(props) { let navigate = useNavigate(); return <AppShell {...props} navigate={navigate} />; }Componente de shell de la aplicación
import React, { Component } from 'react'; import { Outlet } from "react-router-dom"; class AppShell extends Component { componentDidMount() { this.props.navigate('/test'); } render() { return ( <div> <h1>This is app shell</h1> <Outlet /> </div> ); } } export default AppShell;Pensé que el problema radicaba en los ganchos de los componentes, así que intenté implementar la redirección dentro del constructor también, ¡pero nada funcionó para mí!
El problema comercial básico que estoy tratando de resolver aquí es: un usuario será redirigido a una página de inicio de sesión, cada vez que intente navegar por otra página, independientemente del inicio de sesión válido (usuario válido) podría basarse en el token válido en almacenamiento local
¿Alguien podría decir, qué estoy haciendo mal?
La autenticación con respecto a las rutas protegidas es bastante trivial en react-router-dom v6
Cree un componente contenedor que acceda al contexto de autenticación (estado local, tienda redux, almacenamiento local, etc.) y, según el estado de autenticación, represente un componente de Outlet para las rutas anidadas que desea proteger o una redirección a su punto final de autenticación.
Ejemplo AuthWrapper :
const AuthWrapper = () => { const location = useLocation(); const token = !!JSON.parse(localStorage.getItem("token")); return token ? ( <Outlet /> ) : ( <Navigate to="/login" replace state={{ from: location }} /> ); };Usos:
useLocation para obtener la ubicación actual a la que el usuario intenta acceder.Outlet para rutas protegidas anidadas.Navigate componente para navegación declarativa, envía la location actual en estado de ruta para que el usuario pueda ser redirigido después de la autenticación.Ejemplo de uso:
<Router> <Routes> <Route element={<AuthWrapper />}> <Route path="/" element={<App />} /> </Route> <Route path="/login" element={<Login />} /> <Route path="*" element={<Navigate to="/" replace />} /> </Routes> </Router>Inicio de sesión: en el controlador de autenticación, una vez autenticado, configure localStorage y navegue hasta la ubicación que se pasó en el estado de ruta.
function Login() { const { state } = useLocation(); const navigate = useNavigate(); const { from = "/" } = state || {}; const login = () => { localStorage.setItem("token", JSON.stringify(true)); navigate(from); }; return ( <> <h1>Test Me</h1> <button type="button" onClick={login}>Log In</button> </> ); }