Estoy tratando de entender por qué al actualizar la página, el componente se llama varias veces:
MainLayout.tsx: (componente de rutas)
import { FC, ReactElement, useEffect } from 'react' import { Routes, Route, BrowserRouter } from 'react-router-dom' import { createBrowserHistory } from 'history' import { useLocation } from 'react-router-dom' import { Navigate } from 'react-router-dom' import { Outlet } from 'react-router-dom' import { IntroductionPage } from '../pages/introduction/introduction-page' import { useTranslation } from 'react-i18next' import { storage } from '../utils/storage' export const history = createBrowserHistory() export const MainLayout: FC = () => { const { t } = useTranslation() useEffect(() => { console.log('MainLayout:: constructor') }, []) const RequireAuth = (): ReactElement => { const { token } = storage.getState().authReducer let location = useLocation() if (!token) return <Navigate to="/login" state={{ from: location }} /> return <Outlet /> } return ( <BrowserRouter history={history}> <div className="main-wrapper"> <div className="content-wrapper"> <div className="main-content"> <Routes> <Route path="/" element={<Login />} /> <Route path="/login" element={<Login />} /> <Route element={<RequireAuth />}> <Route path="/acceptance" element={<AcceptancePage />} /> <Route path="/introduction/:page" element={<IntroductionPage />} /> </Route> </Routes> </div> </div> </div> </BrowserRouter> ) }página de introducción
Puse el siguiente código en la página de introducción:
useEffect(() => { console.log('IntroductionPage:: constructor') setIntroduction(introductions[+page - 1]) }, [])Estoy actualizando la página de introducción y veo en la consola:
IntroductionPage:: constructor MainLayout.tsx:23 MainLayout:: constructor IntroductionPage:: constructor IntroductionPage:: constructorAgradezco cualquier ayuda
Ah, ya veo por qué el componente de página de IntroductionPage se monta dos veces. El componente RequireAuth se declara dentro de otro componente React. Dado que se vuelve a declarar cada ciclo de renderizado, es una nueva referencia del componente React, por lo que React desmonta la instancia del ciclo de renderizado anterior y monta una nueva instancia. Todos los elementos secundarios que represente también serán instancias nuevas.
Debe declararse por sí solo, fuera de cualquier otro componente de React.
Ejemplo:
const RequireAuth = (): ReactElement => { const { token } = storage.getState().authReducer; const location = useLocation(); if (!token) return <Navigate to="/login" state={{ from: location }} />; return <Outlet />; }; export const MainLayout: FC = () => { const { t } = useTranslation(); useEffect(() => { console.log('MainLayout:: constructor'); }, []); return ( <BrowserRouter history={history}> <div className="main-wrapper"> <div className="content-wrapper"> <div className="main-content"> <Routes> <Route path="/" element={<Login />} /> <Route path="/login" element={<Login />} /> <Route element={<RequireAuth />}> <Route path="/acceptance" element={<AcceptancePage />} /> <Route path="/introduction/:page" element={<IntroductionPage />} /> </Route> </Routes> </div> </div> </div> </BrowserRouter> ); };