
本文详解如何在 React 函数组件中准确识别页面首次加载(含刷新)、路由跳转及局部重渲染,通过 useEffect 依赖数组控制、useLocation 监听路径变化等方法实现精准响应。
本文详解如何在 react 函数组件中准确识别页面首次加载(含刷新)、路由跳转及局部重渲染,通过 `useeffect` 依赖数组控制、`uselocation` 监听路径变化等方法实现精准响应。
在 React 函数组件中,“页面重载”(page reload)本身无法被 JavaScript 直接捕获——因为刷新会销毁整个 JS 执行上下文,所有 Hook 状态清空,组件从头初始化。因此,我们真正需要区分的是:组件首次挂载(对应页面加载/刷新后的初次渲染) vs 后续因状态/props 变化导致的局部重渲染(rerender)。
✅ 正确识别“首次挂载”(模拟 componentDidMount)
使用带空依赖数组的 useEffect,它仅在组件挂载完成后的第一次渲染后执行一次,等效于类组件的 componentDidMount:
useEffect(() => {
console.log("✅ 页面已挂载(首次加载或刷新后)");
}, []); // 空数组 → 仅运行一次⚠️ 注意:这不是监听浏览器刷新事件,而是 React 渲染生命周期的起点信号。只要组件进入 DOM(无论是初始访问还是刷新后),该 effect 就会触发。
✅ 捕获“每次渲染”(含挂载和更新)
省略依赖数组(或传入非空数组),则 effect 在每次渲染完成后都执行,包括首次挂载:
useEffect(() => {
console.log("? 页面已渲染(挂载或状态更新)");
}); // 无依赖数组 → 每次 render 后执行这能帮你调试重渲染频率,但无法单独标识“刷新”。
✅ 检测路由变化(页面级导航,非刷新)
若需在用户跳转路由(如 /home → /about)或刷新后进入新路径时触发逻辑,应结合 react-router-dom 的 useLocation:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function App() {
const { pathname } = useLocation();
useEffect(() => {
console.log(`? 路由已变更至: ${pathname}`);
// 此处可调用初始化函数、埋点、权限校验等
}, [pathname]); // 仅当 pathname 改变时执行
return <div>...</div>;
}✅ 此方案覆盖两种场景:
- 用户点击 Link 导航(SPA 内部跳转)
- 浏览器刷新后重新加载当前路由(pathname 在挂载时即为当前值,effect 仍会执行一次)
⚠️ 常见误区澄清
- ❌ constructor 不适用于函数组件,且在类组件中也不应依赖它判断“页面加载”——它在服务端渲染(SSR)中也会执行,与浏览器刷新无关;
- ❌ useEffect(() => {}, []) 并非“监听页面刷新”,而是“组件挂载”;刷新后组件重建,该 effect 自然再次运行;
- ❌ 无法用纯前端代码 100% 区分“F5 刷新”和“首次访问”,因两者对 React 来说都是全新挂载;若需精确溯源,需服务端配合(如记录 performance.navigation.type 或 session 标识)。
✅ 实用总结:三类场景推荐写法
| 场景 | 推荐方案 | 示例 |
|---|---|---|
| 组件首次加载(含刷新) | useEffect(fn, []) | 初始化全局状态、埋点首屏 |
| 每次渲染(调试/副作用) | useEffect(fn) | 日志记录、性能监控(慎用) |
| 路由变更(含刷新后进新页) | useEffect(fn, [pathname]) | 动态标题、权限检查、页面级数据拉取 |
掌握这些模式,你就能在函数组件中精准控制副作用时机,告别混淆“重载”与“重渲染”的困扰。


















