news 2026/9/24 6:26:00

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/9/24 2:10:54

阿里通义创新突破:8B小模型如何借助智能体记忆框架ReMe挑战大模型!

简介 文章介绍上海交大与阿里通义联合提出的ReMe框架&#xff0c;通过多维度蒸馏、上下文自适应重用和基于效用的精炼三个机制重构记忆生命周期。实验表明ReMe刷新智能体记忆系统SOTA&#xff0c;"记忆扩展效应"显示配备ReMe的Qwen3-8B模型在Avg4和Pass4指标上超越无…

作者头像 李华
网站建设 2026/9/24 2:38:27

EmotiVoice开源项目贡献者激励机制探讨

EmotiVoice开源项目贡献者激励机制探讨 在智能语音技术飞速发展的今天&#xff0c;用户早已不再满足于“能说话”的机器。从虚拟主播到游戏NPC&#xff0c;从有声书平台到无障碍辅助系统&#xff0c;人们对语音交互的期待正从“准确”转向“共情”——声音是否自然&#xff1f…

作者头像 李华
网站建设 2026/9/23 5:19:53

ctfshow_web10

和web9中一样的登录界面&#xff0c;但是之前默认的用户名“admin”没有了随便输入账号密码&#xff0c;没有回显尝试使用万能密码 admin or 11&#xff0c;发现SQL错误回显&#xff0c;应该是SQL注入不小心点到取消&#xff0c;竟然触发下载了一个index.phps返回检查源码&…

作者头像 李华
网站建设 2026/9/23 21:50:21

Kotaemon满减活动规则生成:促销玩法设计

Kotaemon满减活动规则生成&#xff1a;促销玩法设计 在电商大促季&#xff0c;运营团队常常面临一个棘手的问题&#xff1a;如何快速制定一套既吸引用户又不损害利润的满减规则&#xff1f;过去&#xff0c;这依赖于少数资深员工的经验判断&#xff0c;耗时长、主观性强&#x…

作者头像 李华
网站建设 2026/9/24 6:13:54

2、深入了解 PowerShell:功能、优势与 2.0 新特性

深入了解 PowerShell:功能、优势与 2.0 新特性 1. 为何选择 PowerShell 多年来,IT 专业人员一直在寻找能够以一致方式自动化和执行任务的方法。从简单的批处理文件到第三方工具,有许多技术可用于完成这些任务。部分 IT 专业人员还学习了开发语言,如 Visual Basic 或 Java…

作者头像 李华