React Router DOM v6 - 每次路由更改时组件无法重新安装

问题描述 投票:0回答:1
import React from "react";
import { BrowserRouter, Routes, Route, Navigate, Link } from "react-router-dom";

import "./styles.css";

function HomePage() {
  return <div className="page">🏠 Page</div>;
}

function Test() {
  return <div className="page">Test Page</div>;
}

function ApplePage() {
  return <div className="page">🍎 Page</div>;
}

export default function App() {
  return (
    <BrowserRouter>
      <div>
        <Link to="/" className="link">
          Home
        </Link>
        <Link to="/apple" className="link">
          Apple
        </Link>
        <Link to="/test" className="link">
          Test
        </Link>
      </div>
      <Routes>
        <Route
          path="/"
          element={
            <Wrapper>
              <HomePage />
            </Wrapper>
          }
        />

        <Route
          path="/apple"
          element={
            <Wrapper>
              <ApplePage />
            </Wrapper>
          }
        />

        <Route
          path="/test"
          element={
            <Wrapper>
              <Test />
            </Wrapper>
          }
        />
      </Routes>
    </BrowserRouter>
  );
}

const Wrapper = ({ children }) => {
  React.useEffect(() => {
    console.log("wrapper mounted>>>>");
  }, []);

  return children;
};

------

技术 - React-router-dom v6 和 React 18.2.0 根据提供的代码片段,我希望每当路由发生变化时包装器组件都会重新安装。然而,观察到的行为是包装器保持持久安装,无论路由如何变化。

为什么每个路由没有接收到包装器组件的新实例。这可以通过检查包装器安装时记录的控制台日志来确认

沙盒链接

reactjs routes react-router-dom react-routing
1个回答
0
投票

这与 React 在屏幕上渲染组件的方式有关。当react-dom触发渲染时,react会检查哪些组件发生了变化。由于它看到相同的包装器组件,因此它不会卸载并重新安装新的包装器组件(您可以通过将一个 prop 传递给包装器组件上的 1 个组件来测试这一点,您将看到它确实安装和卸载了)。

我不太确定为什么你想在每次 url 更改时运行代码,但如果你这样做了,你就可以

...

function TestPage = ()=><Wrapper><Test/></Wrapper>:


export default function App() {
  return (
    <BrowserRouter>
    ...
      <Routes>
       ...
        <Route
          path="/test"
          element={
           <TestPage/>
          }
        />
      </Routes>
    </BrowserRouter>
  );
}

const Wrapper = ({ children }) => {
  React.useEffect(() => {
    console.log("wrapper mounted>>>>");
  }, []);

  return children;
};

虽然如果你只是想将孩子们包裹在某种布局中,我会这样做:

const Wrapper = ({ children }) => {
  React.useEffect(() => {
    console.log("wrapper mounted>>>>");
  }, []);

  return <Outlet/>
};
  <Routes>
     <Route
          element={
           <Wrapper/>
          }
        >
    enter other routes here
     </Route>
  </Routes>
© www.soinside.com 2019 - 2024. All rights reserved.