如何防止组件在路径更改时卸载?

huangapple go评论111阅读模式
英文:

How to prevent components from unmounting when path changes?

问题

有没有办法阻止路由卸载?在我的应用程序中,我需要在切换路由时保留React状态。

在这里,您可以看到,如果我们更改路由,然后主页对应的 route 组件将会 mountunmount。我不想要这个。

CODESANDBOX DEMO

我已经查看过

如何防止React组件卸载?

如何防止React卸载/重新挂载组件?

但对我不起作用。

index.js

  1. import React from "react";
  2. import { createRoot } from "react-dom/client";
  3. import { BrowserRouter, Routes, Route } from "react-router-dom";
  4. import App from "./App";
  5. import First from "./routes/First";
  6. import Second from "./routes/Second";
  7. const rootElement = document.getElementById("root");
  8. const root = createRoot(rootElement);
  9. root.render(
  10. <BrowserRouter>
  11. <Routes>
  12. <Route path="" element={<App />} />
  13. <Route path="first" element={<First />} />
  14. <Route path="second" element={<Second />} />
  15. </Routes>
  16. </BrowserRouter>
  17. );

App.js

  1. import * as React from "react";
  2. import { Link } from "react-router-dom";
  3. export default function App() {
  4. return (
  5. <div>
  6. <h1>Prevent Routing</h1>
  7. <nav
  8. style={{
  9. borderBottom: "solid 1px",
  10. paddingBottom: "1rem"
  11. }}
  12. >
  13. <Link to="/first">First</Link> |<Link to="/second">Second</Link>
  14. </nav>
  15. </div>
  16. );
  17. }

First.js

  1. import * as React from "react";
  2. import { useEffect } from "react";
  3. import { Link } from "react-router-dom";
  4. export default function First() {
  5. useEffect(() => {
  6. console.log("mounted First");
  7. return () => console.log("unmounted First");
  8. }, []);
  9. return (
  10. <main style={{ padding: "1rem 0" }}>
  11. <Link to="/">Home</Link>
  12. <h2>First</h2>
  13. </main>
  14. );
  15. }

Second.js

  1. import * as React from "react";
  2. import { useEffect } from "react";
  3. import { Link } from "react-router-dom";
  4. export default function Second() {
  5. useEffect(() => {
  6. console.log("mounted Second");
  7. return () => console.log("unmounted Second");
  8. }, []);
  9. return (
  10. <main style={{ padding: "1rem 0" }}>
  11. <Link to="/">Home</Link>
  12. <h2>Second</h2>
  13. </main>
  14. );
  15. }
英文:

Is there a way to stop the route from unmounting? In my app I would need to keep react state between switching the routes.

Here you can see that, if we change route then home respective route component will mount and unmount. I don't want.

CODESANDBOX DEMO

I've looked in

How can I prevent the unmount in React Components?

How can I prevent React from unmounting/remounting a component?

but doesn't work for me.

index.js

  1. import React from &quot;react&quot;;
  2. import { createRoot } from &quot;react-dom/client&quot;;
  3. import { BrowserRouter, Routes, Route } from &quot;react-router-dom&quot;;
  4. import App from &quot;./App&quot;;
  5. import First from &quot;./routes/First&quot;;
  6. import Second from &quot;./routes/Second&quot;;
  7. const rootElement = document.getElementById(&quot;root&quot;);
  8. const root = createRoot(rootElement);
  9. root.render(
  10. &lt;BrowserRouter&gt;
  11. &lt;Routes&gt;
  12. &lt;Route path=&quot;&quot; element={&lt;App /&gt;} /&gt;
  13. &lt;Route path=&quot;first&quot; element={&lt;First /&gt;} /&gt;
  14. &lt;Route path=&quot;second&quot; element={&lt;Second /&gt;} /&gt;
  15. &lt;/Routes&gt;
  16. &lt;/BrowserRouter&gt;
  17. );

App.js

  1. import * as React from &quot;react&quot;;
  2. import { Link } from &quot;react-router-dom&quot;;
  3. export default function App() {
  4. return (
  5. &lt;div&gt;
  6. &lt;h1&gt;Prevent Routing&lt;/h1&gt;
  7. &lt;nav
  8. style={{
  9. borderBottom: &quot;solid 1px&quot;,
  10. paddingBottom: &quot;1rem&quot;
  11. }}
  12. &gt;
  13. &lt;Link to=&quot;/first&quot;&gt;First&lt;/Link&gt; |&lt;Link to=&quot;/second&quot;&gt;Second&lt;/Link&gt;
  14. &lt;/nav&gt;
  15. &lt;/div&gt;
  16. );
  17. }

First.js

  1. import * as React from &quot;react&quot;;
  2. import { useEffect } from &quot;react&quot;;
  3. import { Link } from &quot;react-router-dom&quot;;
  4. export default function First() {
  5. useEffect(() =&gt; {
  6. console.log(&quot;mounted First&quot;);
  7. return () =&gt; console.log(&quot;unmounted First&quot;);
  8. }, []);
  9. return (
  10. &lt;main style={{ padding: &quot;1rem 0&quot; }}&gt;
  11. &lt;Link to=&quot;/&quot;&gt;Home&lt;/Link&gt;
  12. &lt;h2&gt;First&lt;/h2&gt;
  13. &lt;/main&gt;
  14. );
  15. }

Second.js

  1. import * as React from &quot;react&quot;;
  2. import { useEffect } from &quot;react&quot;;
  3. import { Link } from &quot;react-router-dom&quot;;
  4. export default function Second() {
  5. useEffect(() =&gt; {
  6. console.log(&quot;mounted Second&quot;);
  7. return () =&gt; console.log(&quot;unmounted Second&quot;);
  8. }, []);
  9. return (
  10. &lt;main style={{ padding: &quot;1rem 0&quot; }}&gt;
  11. &lt;Link to=&quot;/&quot;&gt;Home&lt;/Link&gt;
  12. &lt;h2&gt;Second&lt;/h2&gt;
  13. &lt;/main&gt;
  14. );
  15. }

答案1

得分: 1

React Router在组件不匹配path时总是会卸载该组件。

你可以通过将两个组件与双重路由组合来解决这个问题,每个组件可以根据当前的path确定要渲染什么。

因此,主要路由看起来会像这样:

  1. <Route path={[ '/first', '/second' ]}>
  2. <First {...{}} />
  3. <Second {...{}} />
  4. </Route>

然后在组件中使用useLocation来切换渲染:

  1. import { useLocation } from "react-router-dom";
  2. function First(props) {
  3. const location = useLocation();
  4. if (location.pathname !== '/first') {
  5. return null
  6. }
  7. }
英文:

React Router will always unmount the component when it's not matched by a path.


You could fix this by combining both Components with a double route, each component can determine what he will render based on the current path.

So the main routing will look something like:

  1. &lt;Route path={[ &#39;/first&#39;, &#39;/second&#39; ]}&gt;
  2. &lt;First {...{}} /&gt;
  3. &lt;Second {...{}} /&gt;
  4. &lt;/Route&gt;

Then use useLocation in the component to toggle the render:

  1. import { useLocation } from &quot;react-router-dom&quot;;
  2. function First(props) {
  3. const location = useLocation();
  4. if (location.pathname !== &#39;/first&#39;) {
  5. return null
  6. }
  7. }

huangapple
  • 本文由 发表于 2023年1月9日 19:00:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定