news 2026/6/17 17:49:22

react中useEffect的用法,以及订阅模式的原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
react中useEffect的用法,以及订阅模式的原理

退出登录的功能示例

import React, { FC, useEffect } from 'react' import { Button, message } from 'antd' import { Link, useNavigate } from 'react-router-dom' import { UserOutlined } from '@ant-design/icons' import { useDispatch } from 'react-redux' // import { useRequest } from 'ahooks' import { LOGIN_PATHNAME } from '../router' // import { getUserInfoService } from '../services/user' import { removeToken } from '../utils/user-token' import useGetUserInfo from '../hooks/useGetUserInfo' import { logoutReducer } from '../store/userReducer' const UserInfo: FC = () => { const nav = useNavigate() const dispatch = useDispatch() // const { data } = useRequest(getUserInfoService) // ajax // const { username, nickname } = data || {} const { username, nickname } = useGetUserInfo() // 从 redux 中获取用户信息 function logout() { dispatch(logoutReducer()) // 清空了 redux user 数据 removeToken() // 清除 token 的存储 message.success('退出成功') } // 监听用户状态变化,如果用户已退出则跳转到登录页 useEffect(() => { if (!username) { nav(LOGIN_PATHNAME) } }, [username, nav]) const UserInfo = ( <> <span style={{ color: '#e8e8e8' }}> <UserOutlined /> {nickname} </span> <Button type="link" onClick={logout}> 退出 </Button> </> ) const Login = <Link to={LOGIN_PATHNAME}>登录</Link> return <div>{username ? UserInfo : Login}</div> } export default UserInfo

用法说明

这个useEffect是用来监听用户登出状态并执行相应跳转的核心逻辑。让我详细解释一下它是如何工作的:

useEffect(() => { if (!username) { nav(LOGIN_PATHNAME) } }, [username, nav])

这段代码的作用是:

  1. 监听依赖项:第二个参数[username, nav]表示这个 effect 依赖于usernamenav这两个变量
  2. 触发条件:只有当usernamenav的值发生变化时,才会重新执行 effect 中的函数
  3. 执行逻辑
    • 检查 username 是否为空(falsy值)
    • 如果为空,就调用nav(LOGIN_PATHNAME)跳转到登录页面

具体流程

当你点击"退出"按钮时:

  1. 触发 logout 函数
  2. logout 函数中执行dispatch(logoutReducer())
  3. logoutReducer 会把 Redux store 中的用户信息重置为初始状态{ username: '', nickname: '' }
  4. 由于 useGetUserInfo() hook 会订阅 Redux store 中的用户信息,所以 username 变量会从实际用户名变为 ' '
  5. useEffect检测到 username 发生了变化,于是重新执行其中的函数
  6. 此时!username为 true(因为 username 是空字符串),所以执行nav(LOGIN_PATHNAME)
  7. 页面跳转到登录页/login

订阅模式介绍

在 React 和 Redux 中,"订阅"是一种设计模式,用于监听状态变化并在状态更新时自动通知相关组件。让我详细解释一下这个过程:
Redux 订阅机制的工作原理
Redux 使用发布-订阅(Publish-Subscribe)模式来实现状态变化的通知机制。下面是具体的工作流程:
1. 订阅建立:当组件使用 useGetUserInfo() 这样的自定义 hook 时,它内部会使用 react-redux 提供的 useSelector hook 来订阅 Redux store 中的特定状态。
2. 状态变化检测:每当 dispatch 一个 action(例如 logoutReducer())时,Redux 会更新 store 中的状态。
3. 通知机制:Redux 会比较更新前后的状态,如果发现有变化,就会通知所有订阅了这部分状态的组件。
4. 组件重新渲染:接收到通知的组件会使用新的状态值重新渲染。

具体到我们的例子

// useGetUserInfo hook 内部大概是这样的 export default function useGetUserInfo() { const { username, nickname } = useSelector<StateType>(state => state.user) return { username, nickname } } // 在 UserInfo 组件中 const { username, nickname } = useGetUserInfo()

当执行dispatch(logoutReducer())时:

  1. Redux store 中的 user 状态从{ username: 'actual_username', nickname: 'actual_nickname' }变成了{ username: '', nickname: '' }
  2. Redux 检测到这个变化
  3. 所有使用 useSelector 订阅了state.user的组件都会收到通知
  4. UserInfo 组件重新渲染,此时 username 变量的值变成了 ' '

useEffect 如何响应变化

useEffect(() => { if (!username) { nav(LOGIN_PATHNAME) } }, [username, nav])

这里的 [username, nav] 是依赖数组,告诉 React:"当 username 或 nav 变化时,请重新执行这个 effect"。
所以整个流程是:
1. 用户点击退出按钮
2. dispatch logoutReducer() 清空用户信息
3. Redux 通知订阅了用户信息的所有组件
4. UserInfo 组件重新渲染,username 更新为空字符串
5. useEffect 检测到 username 变化,执行回调函数
6. 因为 !username 为 true,执行跳转到登录页
这就是所谓的"订阅模式"——组件订阅了状态的一部分,当这部分状态变化时,组件会自动得到通知并做出响应。这是一种非常高效且常用的 React 状态管理模式。

Effect的概念

Effect 是 React 中的一个核心概念,指的是在组件渲染之外执行的操作。这些操作通常包括:

  1. 数据获取(API 请求)
  2. 订阅(如 WebSocket 连接)
  3. 手动修改 DOM
  4. 定时器(setTimeout, setInterval)
  5. 日志记录
  6. 页面跳转(路由导航)

在传统的 Class 组件中,这些操作通常在 componentDidMount、componentDidUpdate 和 componentWillUnmount 等生命周期方法中处理。

useEffect Hook

React Hooks 引入了 useEffect 来统一处理这些副作用。它的基本语法是:

useEffect(() => { // 副作用代码 // 可选的清理函数 return () => { // 清理代码 }; }, [/* 依赖数组 */]);

这里的 effect 做的事情是:

  1. 副作用操作:页面跳转 (nav(LOGIN_PATHNAME))
  2. 触发条件:当 username 变为空时
  3. 依赖项:username 和 nav

为什么叫"Effect"

之所以叫做"effect",是因为它处理的是"副作用",即不是直接参与渲染过程,但却会产生重要影响的操作。在函数式编程中,纯函数不应该有任何副作用,而 effect 正是用来处理这些不可避免的副作用的机制。

Effect 的工作机制

  1. 初始化:组件首次渲染后,执行 effect 函数(如果提供了依赖数组且为空,则只执行一次)
  2. 依赖更新:当依赖数组中的任何一个值发生变化时,重新执行 effect 函数
  3. 清理:如果 effect 函数返回了一个清理函数,它会在下一次 effect 执行前或者组件卸载时被调用

在我们的例子中:

  • 当用户点击退出按钮,触发 logout
  • logout 清除了 Redux 中的用户信息
  • username 从真实用户名变成空字符串
  • useEffect 检测到 username 变化,执行 effect 函数
  • effect 函数发现!username为真,执行页面跳转

这就是 effect 的完整工作流程:监听特定状态变化,当变化发生时执行相应的副作用操作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/17 15:36:12

Kotaemon能否识别建筑图纸?CAD信息提取设想

Kotaemon能否识别建筑图纸&#xff1f;CAD信息提取设想 在智能建造与数字孪生快速演进的今天&#xff0c;一个现实问题正困扰着无数工程师&#xff1a;如何从成百上千张CAD图纸中快速找到“三楼东侧走廊的配电箱型号”&#xff1f;传统方式依赖经验丰富的技术人员逐图翻阅、交叉…

作者头像 李华
网站建设 2026/6/16 16:59:43

Kotaemon是否适合非技术用户?我们测试了它的易用性

Kotaemon是否适合非技术用户&#xff1f;我们测试了它的易用性 在智能助手逐渐渗透企业日常运营的今天&#xff0c;越来越多团队希望快速搭建一个能回答内部问题、处理常见任务的AI系统。但现实是&#xff0c;大多数开源框架仍然停留在“开发者专属”的阶段——你需要懂Python、…

作者头像 李华
网站建设 2026/6/16 5:58:55

Kotaemon Excel数据读取:结构化信息导入技巧

Kotaemon Excel数据读取&#xff1a;结构化信息导入技巧 在企业日常运营中&#xff0c;大量关键业务数据仍以Excel表格的形式存在——销售报表、客户清单、产品目录……这些文件每天被反复打开、修改、转发&#xff0c;却往往“沉睡”在本地磁盘或共享文件夹里&#xff0c;难以…

作者头像 李华
网站建设 2026/6/17 7:28:13

2026论学生餐行业变化与未来

2.86亿在校学子的餐桌&#xff0c;一头连着千万家庭的牵挂&#xff0c;一头系着国家未来的根基。学生餐行业的每一次迭代&#xff0c;都是民生福祉的刻度攀升&#xff1b;每一步前行&#xff0c;都是“健康中国”战略的生动践行。从政策兜底筑牢安全底线&#xff0c;到技术赋能…

作者头像 李华
网站建设 2026/6/16 2:17:33

Python Tkinter 实战:手把手教你写一个批量字符添加工具

目录Python Tkinter 实战&#xff1a;手把手教你写一个批量字符添加工具&#x1f4a1; 需求分析&#x1f680; 效果演示&#x1f4bb; 代码实现1. 界面布局2. 核心逻辑3. 完整代码 (text_wrapper.py)&#x1f6e0;️ 如何使用专栏导读 &#x1f338; 欢迎来到Python办公自动化专…

作者头像 李华