前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库React 用户操作放事件还是 useEffect
ReReact副作用与同步

用户点击触发的逻辑为什么通常放事件处理器,而不是 useEffect?

如果操作发生的原因是某次明确交互,就在那次事件流程里表达;Effect 用来维持外部系统与当前输入一致。

前端进阶之旅 · 一题精讲更新于 2026.09.06
React#副作用与同步#Effect
先看核心答案
理解线索

根据操作为何发生来分类

  1. 明确交互用户点击提交,应处理这一次提交意图
  2. 持续同步当前文档变了,需要切换对应的外部订阅
  3. 纯展示计算能从输入直接得到的内容,在渲染中计算

“包含副作用”不足以证明应使用 Effect;事件处理器同样可以执行外部操作。

核心回答

先记住这个答案

事件处理器知道用户执行了什么动作,可以携带这次动作的参数并处理成功、失败和后续步骤。Effect 则根据响应式输入变化重新同步,并不天然知道变化是由哪次用户意图引起。提交订单或发送反馈若绕成设置一个布尔值再由 Effect 发请求,会增加中间状态和重复触发边界。事件中可以更新 state,随后需要与该状态保持同步的外部资源仍可交给独立 Effect 管理。

  • 一次动作的因果关系放在事件流程中
  • 持续匹配当前状态的资源交给同步流程
  • 状态变化与外部操作之间不要增加无意义的触发标记

发送反馈不需要经过一个中间布尔状态

假设用户填写意见后点击发送。事件处理器可以读取本次输入,建立请求状态,等待结果并显示成功或错误。如果先 setShouldSend(true),再让 Effect 观察它发送,就还要解释何时重置、第二次点击是否改变值、输入改变是否应该再次发送等额外问题。

特别是依赖同时包含输入内容时,发送标记仍为 true 的期间修改文本可能触发另一轮请求;为了阻止它而删除输入依赖,又可能使用旧内容。把命令放回事件流程,能直接保留本次提交参数,并把按钮禁用、重复提交和服务端幂等规则表达在同一个业务动作中。

打开详情之后,有些工作仍然适合 Effect

点击某商品可以只更新 selectedId,页面根据它展示详情。若外部实时服务需要持续订阅当前商品库存,那么订阅应与当前 selectedId 保持一致,无论这个值来自点击、路由恢复还是父组件传入,都应切换到正确的资源。这类关系适合由 Effect 建立和清理。

因此同一次交互可以同时涉及事件与同步,但职责不同。事件说明用户选择了什么;Effect 说明组件当前展示这个对象时,外部连接应该是什么。不要把建立连接的代码复制到所有可能修改 selectedId 的事件里,否则新增一个入口时很容易漏掉同步。

用可恢复的业务状态表达异步过程

事件处理器中执行异步操作仍需要处理竞争和错误,例如两次提交是否允许并行、页面离开后怎样显示结果、请求失败后是否保留输入。事件位置本身不保证只执行一次,重复点击和网络重试依然可能发生。关键写入应有清楚的请求标识与服务端幂等策略。

自动保存则要根据产品语义判断:输入停顿后保存当前草稿是一种持续同步需求,可以使用带取消与版本检查的同步机制;用户明确点保存按钮则属于一次事件。两者可以共存,但需要区分保存版本,避免自动保存的迟到结果覆盖用户刚刚确认的内容。

回答前,多想一步

容易答错的地方

所有请求都应该放在 useEffect
请求只是外部操作的一种实现,放置依据是触发原因。用户命令、框架数据加载和持续同步各有合适位置,不能只看函数名里是否包含 fetch。
移到点击事件就天然不会重复提交
用户仍可以重复点击,客户端或网络层也可能重试。需要明确提交状态、去重范围与服务端语义,不能用代码位置代替可靠的业务防重。
试着用自己的话回答

面试官还会怎么问?

事件处理器需要放在 Effect 依赖数组里吗?

如果 Effect 不读取它,就没有这项依赖。不要为了共享一段逻辑让事件和 Effect 相互调用;可以抽取普通纯函数或明确的服务操作,再分别组织触发流程。

页面一显示就需要建立连接,算事件吗?

如果要求连接持续匹配当前展示的参数,无论页面如何进入都应生效,这更像同步关系。Effect 应配对清理,保证参数切换和页面离开时资源正确释放。

点击后计算合计需要 Effect 吗?

若合计只是当前商品和数量的纯函数,可以在渲染时计算。点击事件更新数量即可,不必再保存一份合计并用 Effect 同步,否则会增加可过期的冗余状态。

从一道题,走向一组知识

把知识连起来

副作用与同步

React 所说的“用 Effect 与外部系统同步”具体是什么意思?

进一步判断哪些外部关系需要随当前界面输入保持同步。

副作用与同步

React 中由 props/state 计算出的值为什么通常不该放进 Effect 再 setState?

展示值能直接从输入计算时,还可以完全省去 Effect 与额外 state。

参考资料

  • Separating Events from Effects
  • You Might Not Need an Effect

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 发送反馈不需要经过一个中间布尔状态
  3. 打开详情之后,有些工作仍然适合 Effect
  4. 用可恢复的业务状态表达异步过程
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑