React返回上一个页面,会重新挂载吗

在 React 中,当你使用 React Router 或其他导航方法返回到上一个页面时,默认情况下,返回的页面会重新挂载。也就是说,组件会重新执行它的生命周期方法(或钩子函数),例如 useEffect、useState 的初始状态设定等。

1、默认情况下组件会重新挂载

使用 useNavigate 或者浏览器的返回按钮时,返回到之前的页面会触发该页面组件的重新挂载。通常来说,页面会重新加载,并且该组件的 useEffect(如果设置了依赖项为 [])会再次执行。

bash 复制代码
import React, { useEffect } from 'react';

const PreviousPage = () => {
  useEffect(() => {
    console.log('Component mounted');
  }, []);

  return <div>Previous Page</div>;
};

当你从这个页面导航到其他页面再返回时,console.log('Component mounted') 会再次打印,因为组件重新挂载了。

2、如何避免组件重新挂载

如果你想避免组件重新挂载(比如保持表单数据、滚动位置等),可以通过以下几种方法来实现页面的缓存或状态的持久化。

bash 复制代码
import { Outlet } from 'react-router-dom';

const Layout = () => {
  return (
    <div>
      <header>Header</header>
      <Outlet /> {/* 这里放置的子组件会根据路由切换,而 Layout 不会重新挂载 */}
    </div>
  );
};

2.1、使用 React Router 的 或嵌套路由

在 React Router v6 中,如果你将组件放在 Layout 组件或使用嵌套路由时,返回页面时可以避免某些组件的重新挂载(通常是保持页面布局组件)。

bash 复制代码
import { Outlet } from 'react-router-dom';

const Layout = () => {
  return (
    <div>
      <header>Header</header>
      <Outlet /> {/* 这里放置的子组件会根据路由切换,而 Layout 不会重新挂载 */}
    </div>
  );
};

这样,Layout 组件在页面切换时不会重新挂载,只会替换 Outlet 中的内容,允许你保持一些全局布局或共享状态。

2.2、缓存页面状态

使用状态管理工具(如 Redux、Context API),或者将状态保存在 localStorage 或 sessionStorage 中,可以在返回页面时恢复状态。

bash 复制代码
import React, { useState, useEffect } from 'react';

const FormPage = () => {
  const [inputValue, setInputValue] = useState(() => {
    // 从 localStorage 恢复初始值
    return localStorage.getItem('formInput') || '';
  });

  // 当 inputValue 改变时,保存到 localStorage
  useEffect(() => {
    localStorage.setItem('formInput', inputValue);
  }, [inputValue]);

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
    </div>
  );
};

export default FormPage;

2.3、 使用 React 的 useMemo 或 useRef

如果组件中的某些部分需要在重新挂载时保持不变,可以使用 useMemo 或 useRef 来缓存那些不需要每次重新计算的数据。

  • useMemo:用来记住计算结果,直到依赖项发生变化。
  • useRef:用于存储跨渲染周期保持不变的值。
bash 复制代码
const ExpensiveComponent = () => {
  const memoizedValue = useMemo(() => {
    return performExpensiveCalculation();
  }, []);

  return <div>{memoizedValue}</div>;
};

2.4、使用 React Query 等工具缓存数据

React Query 等库可以帮助你缓存请求数据。当你返回到一个页面时,它不会重新发起网络请求,而是使用缓存的数据来重新渲染页面。

3、 React Router 提供的 useLocation 的状态传递

如果你使用 React Router 的 navigate 时传递状态,你可以在返回页面时通过 useLocation 恢复状态,而不是让组件重新计算或重新挂载。

bash 复制代码
import { useNavigate, useLocation } from 'react-router-dom';

const PageComponent = () => {
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    if (location.state) {
      console.log('Restored state:', location.state);
    }
  }, [location.state]);

  return <div>Some content</div>;
};

4、使用 React Router 的 keep-alive 插件

React Router 没有内置的"缓存页面"功能,但你可以使用第三方插件,比如 react-activation,实现页面的"保活"功能,即保持页面状态不变而不重新挂载。

5、总结

  • 1、默认情况下,返回到之前的页面会重新挂载组件,即重新执行组件的生命周期或钩子函数。
  • 2、避免组件重新挂载的方法:
    使用 React Router 的嵌套路由或布局组件。
    通过 localStorage 或 sessionStorage 缓存状态。
    使用 useMemo、useRef 缓存部分计算结果。
    使用 React Query 等工具缓存数据。
    使用 react-activation 等插件保持页面不重新挂载。
相关推荐
墨菲安全3 分钟前
NPM组件 @ivy-shared-components/iconslibrary 等窃取主机敏感信息
前端·npm·node.js·npm组件投毒·主机敏感信息窃取·恶意npm包
盛夏绽放37 分钟前
Excel导出实战:从入门到精通 - 构建专业级数据报表的完整指南
开发语言·javascript·excel·有问必答
Mintopia40 分钟前
🌀曲面细分求交:在无限细节中捕捉交点的浪漫
前端·javascript·计算机图形学
Mintopia43 分钟前
🧙‍♂️用 Three.js 判断一个点是否在圆内 —— 一次圆心和点的对话
前端·javascript·three.js
liliangcsdn1 小时前
mac mlx大模型框架的安装和使用
java·前端·人工智能·python·macos
CssHero1 小时前
基于vue3完成领域模型架构建设
前端
PanZonghui1 小时前
用项目说话:我的React博客构建成果与经验复盘
前端·react.js·typescript
挽淚1 小时前
JavaScript 数组详解:从入门到精通
javascript
言兴1 小时前
教你如何理解useContext加上useReducer
前端·javascript·面试
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GoodCheapFast(Good - Cheap - Fast三选二开关)
前端·javascript·css·vue.js·tailwindcss