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 根据提供的代码片段,我希望每当路由发生变化时包装器组件都会重新安装。然而,观察到的行为是包装器保持持久安装,无论路由如何变化。
为什么每个路由没有接收到包装器组件的新实例。这可以通过检查包装器安装时记录的控制台日志来确认
这与 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>