惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
T
Threatpost
D
DataBreaches.Net
B
Blog RSS Feed
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
N
Netflix TechBlog - Medium
O
OpenAI News
Webroot Blog
Webroot Blog
Stack Overflow Blog
Stack Overflow Blog
Recent Announcements
Recent Announcements
Google Online Security Blog
Google Online Security Blog
SecWiki News
SecWiki News
H
Help Net Security
Forbes - Security
Forbes - Security
N
News and Events Feed by Topic
aimingoo的专栏
aimingoo的专栏
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
B
Blog
H
Heimdal Security Blog
博客园 - 三生石上(FineUI控件)
C
CERT Recently Published Vulnerability Notes
L
Lohrmann on Cybersecurity
G
Google Developers Blog
Scott Helme
Scott Helme
C
CXSECURITY Database RSS Feed - CXSecurity.com
罗磊的独立博客
V
Visual Studio Blog
L
LINUX DO - 热门话题
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
F
Full Disclosure
C
Cisco Blogs
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
F
Fortinet All Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google DeepMind News
Google DeepMind News
S
Security Affairs
P
Privacy & Cybersecurity Law Blog
S
Secure Thoughts
V
V2EX
雷峰网
雷峰网
Security Latest
Security Latest
H
Hacker News: Front Page
TaoSecurity Blog
TaoSecurity Blog
M
MIT News - Artificial intelligence

React

react 的旧文档网站,切换语言到中文,直接跳到新文档?? - V2EX react 这个技术栈到底是如何做到每天都有新发现的? 除了 next.js,在 2026 年,还有哪些 React 全栈框架推荐? - V2EX React 列表虚拟化如何实现使用 CSS Grid 布局的同时支持拖动元素? - V2EX 想不通, React 现代框架的设计者,为什么内置的 onClick 不默认防抖? - V2EX 关于低代码的选型,请佬们帮我分析一下 - V2EX 将 Markdown 文件导入为 React 组件 - 写作文档,即时获取交互式演示 - V2EX 现代 React 应用卡顿的主要原因是什么?组件库 vs 重渲染机制 - V2EX 前端开发进军 server 端还是问题很多 - V2EX 问一下, expo react native 的 TextInput 在小米系统下,显示有问题。大家有遇到么,如何解决。 - V2EX React Suite v6:面向现代化的稳健升级 - V2EX 各位总们,开发兼容到 ios 11 的 APP, RN 推荐吗 - V2EX expo-image 在使用时候必须要加 style 属性 ? - V2EX 佬们, 咨询一个前端 React 的开发效率问题, 就是如果想快速实现一个界面组件的效果,只需要 render 部分, 有什么好用的工具吗? - V2EX 2025 快过完了,有 ssr 需求的项目现在最佳选择是什么? - V2EX 在 react 中使用 signals 库 - V2EX react charts 技术选型 - V2EX 折腾了好几天总算在 windows 系统本地打包 expo 项目出 apk 了,分享下经验 - V2EX 一个 RN 小游戏代码修改的活 - V2EX 为什么 React-Native 总是昨天还能编译,今天就报错了 - V2EX React 19 下有什么方便点的组件? Arco Design 用起来还是有些问题 时隔多年再次用 react,请问 ahooks 的 useMemoizedFn 和 react 内置的 useEffectEvent 有什么异同? - V2EX 来个专业写 移动 web 前端的, React - V2EX 谁有闲工夫, React,帮忙定位并处理下 BUG react antd 就是包了巧克力的屎 - V2EX 提问一个 React 的问题 React 多人开发怎么确保性能,有没有最佳实践 - V2EX zustand create 出来的 useStore,需不需要 destory? - V2EX 关于 React: - V2EX Metis UI:下一代 React 组件库,重新定义前端开发体验 - V2EX React 组件库 Gluestack 出现多个恶意软件包 gpt 给我搞懵了,是我对 Suspense 理解有误吗? 有用 LiveKit 开发过视频语音会议系统的嘛 - V2EX RN 怎么构建输出 Java 的原生工程啊? 大佬们,有没有好用的 react.js 画布组件? 技术文章翻译: React 协调机制 - V2EX 不知道是 react 不行还是阿里不行, 或者是我电脑不行? 访问阿里云卡卡的.滚动一愣一愣的. 不敢相信在 2025,怎么自己 build/bundle + self-host 一个 ESM 版本的 react.js 和 react-dom.js 也是一个找不到官方答案的问题。问了 AI,答案也不靠谱 - V2EX 有没有熟悉 react native 的老哥,求帮忙看个问题 - V2EX React 写的越多,就越想直接操作 DOM - V2EX react native 有类似 antd/x 的 ai 对话组件库吗 - V2EX react 最佳技术栈是什么? - V2EX 是不是都用 expo-image 了,分享下 react-native-turbo-image - V2EX 用 AI 写了个 react 的资讯网站,才发现 SEO 很差,怎么办 - V2EX 反思,我写的前端的 react 味是不是太重了 - V2EX 小白求助,React 项目无法修改 - V2EX 被 antd 惯坏了,别的组件库用的很难受,大家有这种感觉吗? - V2EX React 学习曲线要比 Vue 陡峭许多呀 - V2EX 请教一个 react native FlatList 的问题 - V2EX
请教一个关于 useEffect 依赖的问题 - V2EX
ooo4 · 2025-02-20 · via React

这是一个创建于 479 天前的主题,其中的信息可能已经有所发展或是发生改变。

请教一个关于 useEffect 依赖的问题

最近在学习 react 和 nextjs ,算初学者,感觉我写的很多 useEffect eslint 都提示缺少依赖,但其实我觉得写的依赖已经够了

比如这样

  const [conversation, setConversation] = useState<Conversation[]>([])
  useEffect(() => {
    if (currentChatTitle) {
      setConversation(
        conversation.map((i) => {
          return {
            ...i,
            title: i.id === currentChatId ? currentChatTitle : i.title,
          }
        })
      )
    }
  }, [currentChatId, currentChatTitle])

eslint 就说缺少conversation这个依赖,但是加了之后就无限执行这个 useEffect 回调了,其实我连这个currentChatId都不想加入依赖

eslint 也给了解决方案就是改成setXXX((prev)=>xxx),但这样好麻烦啊,或者就是 disable 掉这一行

  useEffect(() => {
    if (currentChatTitle) {
      // 改成`setXXX((prev)=>xxx)`
      setConversation((conversation) =>
        conversation.map((i) => {
          return {
            ...i,
            title: i.id === currentChatId ? currentChatTitle : i.title,
          }
        })
      )
    }
  }, [currentChatId, currentChatTitle])

请问下各位平时会关掉这个eslintreact-hooks/exhaustive-deps这个规则吗

darkengine

1

darkengine      2025 年 2 月 20 日

能说说你这个代码要实现什么效果么,感觉逻辑不太对,可能要多引入一个 state

MossFox

2

MossFox      2025 年 2 月 20 日   ❤️ 2

就得用后面这段方案。否则的话,前面那个例子能跑通的原因也只是碰巧了,在于 每次因为其他 state 的变化导致的组件 rerender ,顺便更新了你的这个 useEffect 中的 conversation 。

如果你用前面的方式发现某次显示的 conversation 是旧数据,那么就是掉坑里了。

至于这个场景,我感觉可以试一下用 useMemo 。如果是要根据两个条件来筛选当前 active 的 conversation 或者类似的,那就
const activeConversation = useMemo(() => {
// 在这里面 map

}, [conversation, xxx_id, xxx_title]);

这样还能节约一次重绘,useEffect 那种 set 状态相当于 中括号里的变量变化一次重绘,useEffect 触发完因为 set 了 state 又触发一次重绘。useMemo 则可以是 一次绘制里面直接根据中括号里面的值,这一轮绘制就给变化的结果返回去。

ooo4

3

ooo4      2025 年 2 月 20 日

@darkengine 就是在/bar/foo 下的这个 page.tsx 更新了一个状态 currentChatTitle ,然后在/bar 下的 page.tsx 要触发 currentChatTitle 的副作用,再更新额外的状态

ooo4

4

ooo4      2025 年 2 月 20 日

@MossFox thanks ,我明天试试,顺便在看看文档

wgbx

5

wgbx      2025 年 2 月 21 日

react 的心智负担很大,往往对初学者不友好,首先,开发者理解的依赖和 react 需要的依赖是不一样的,你这个代码想在 currentChatId, currentChatTitle 变化时执行函数,但是每次函数更新时,conversation 因为在副作用引用了,也会更新,所以也需要监听,合理的办法确实是通过 setConversation 返回当前值进行更新

如果你连 currentChatId 都不想加,说明 currentChatId 本身是常量或者不更新的值,你应该使用 useMemo 包裹起来,避免重复计算

eslint 的规则不能关闭,他确实能反映依赖的问题,但是 ahooks 是必须使用的,作为 react 的 hooks 包装,能节省很多代码,另外你这个写法是不能够优化,currentChatTitle 在什么时候更新?初始化更新应该放在 useMount 上,事件触发应该放在函数里,这种情况的副作用不多见

mizuki9

6

mizuki9      2025 年 2 月 21 日

eslintreact-hooks/exhaustive-deps 规则应该设置报 warning ,不要报 error 。
多个 state 有时候是可以合并成一个的,某些情况可以解决 useEffect 依赖报 warning 。
明确知道自己逻辑正确的时候,忽略 warning 就好了,react 写多了就习惯了

FlashEcho

7

FlashEcho      2025 年 2 月 21 日

set 函数可以传入一个函数作为参数,也很清晰啊,这个更新函数接受旧值,返回新值,而且还更安全。如果 set 函数传入值,获取到外面的旧的 conversation 怎么办,传入函数就没问题了

上面有人推荐使用 useMemo ,我不太建议,看起来你的这更新就是数组替换一下,这个渲染也不太复杂,没有必要缓存,缓存本身也是有成本的,无脑 useMemo 不是全是好处的,不考虑本身的成本,心智负担还变重了

darkengine

8

darkengine      2025 年 2 月 21 日

@MossFox 的方案是对的,就是要引入一个 activeConversation 用来渲染当前标题,不应该是去改 conversation (应该叫 conversations?)

wiluxy

9

wiluxy      2025 年 2 月 21 日

典型的滥用 useEffect 的例子,@MossFox 的方案是对的,至于 @chesha1 说的不推荐 useMemo ,这里 useMemo 的作用类似于派生状态,心智负担比用 useEffect 小

ooo4

10

ooo4      2025 年 2 月 21 日

@wgbx 不加这个 currentChatId 能满足我的功能,但 eslint 会抛出警告,加了又不满足我的功能了,react 太难了。

wiluxy

11

wiluxy      2025 年 2 月 21 日

@ooo4 如果不加这个 currentChatId 可以满足你的功能,非要用 useEffect 的话,可以考虑一下用 useReducer 组织状态

```typescript
import React, {useEffect, useReducer, useState} from "react"

type Conversation = {
id:string
title:string
[key:string]:unknown
}

const initialState:Conversation[] = [
{id:'1',title:"title-1"},
{id:'2',title:"title-2"},
{id:'3',title:"title-3"},
]

function App() {
const [currentChatId,setCurrentChatId] = useState("")
const [currentChatTitle,setCurrentChatTitle] = useState("")

const [conversation,setConversation] = useReducer<
React.Reducer<
Conversation[],
(prev:Conversation[],curChatId:typeof currentChatId)=>Conversation[]
>
>((prev,action)=>{
console.log(123)
return action(prev,currentChatId)
},initialState)

useEffect(()=>{
if(currentChatTitle){
setConversation((prev,curChatId)=>{
console.log({curChatId})
return prev.map(i=>{
return {
...i,
title: i.id === curChatId ? currentChatTitle : i.title,
}
})
})
}
},[currentChatTitle])

return <div>
<label htmlFor="currentChatId">currentChatId:</label>
<input type="text" id="currentChatId" value={currentChatId} onChange={(e)=>setCurrentChatId(e.target.value)} />
<label htmlFor="currentChatTitle">currentChatTitle:</label>
<input type="text" id="currentChatTitle" value={currentChatTitle} onChange={(e)=>setCurrentChatTitle(e.target.value)} />
<ul>
{
conversation.map(i=>{
return <li key={i.id}>{i.title}</li>
})
}
</ul>
</div>
}

export default App;

```

ooo4

13

ooo4      2025 年 2 月 21 日

@MossFox 改成了 useMemo 解决我的问题了,逻辑也清晰多了
```js
const conversationInfo = useMemo(() => {
return conversation.map((i) => ({
...i,
active: i.id === currentChatId,
title:
currentChatTitle && i.id === currentChatId ? currentChatTitle : i.title,
}))
}, [conversation, currentChatTitle, currentChatId])
```

NerdHND

15

NerdHND      2025 年 2 月 21 日

多用 useMemo, 如果实在是需要通过变更修改 state, 用 useReducer 也可以解决很多问题. 当然, 还是最好多构建单项数据流, 少用 flag

yunyuyuan

16

yunyuyuan      2025 年 2 月 21 日

2 楼说的很详细了。其实只要理解 react 的每一次渲染都是一个“单独”的闭包,里面的所有 state 都只代表当前渲染,把它当作一次性的,只用来计算和展示,就能搞明白大部分问题

FlashEcho

17

FlashEcho      2025 年 2 月 21 日

@wiluxy #9 确实,我都没想到直接不要 useEffect 这个问题,最好做法肯定还是直接在 currentChatId 和 currentChatTitle 变化的事件内部直接用 setConversation 。我不推荐 useMemo ,主要是 useMemo 用起来尤其麻烦,需要注意 Memo 的依赖从头到尾都没问题,不然如果传递的层数比较深,谁随手搞一下 props 缓存就失效了(还有一些别的 memo 失效的场景,以前看的文章有点忘记了),所以我的想法是 profiler 之后再优化比较好?不太懂 react ,不知道这个做法是否最优

wiluxy

18

wiluxy      2025 年 2 月 21 日

@chesha1 useMemo 、useEffect 漏依赖的问题,可以装个 eslint 插件(@eslint-react/eslint-plugin
)辅助查看依赖有没有问题,遵循 hooks 规则写下去,等以后 react compiler 完善自动优化吧,现在没有性能问题就不用管太多了,只要功能正常、没有性能问题,re-render 不是什么大事情,老是想着最佳实践很累的。

X_Del

19

X_Del      2025 年 2 月 21 日   ❤️ 3

不一定要多用 useMemo ,但一定要少用 useEffect 。
见到很多 React 新人 useEffect 的时候,会创建很多多余的 state ,比如下面这种代码:

```
const [lightColor, setLightColor] = useState<'red' | 'yellow' | 'green'>('red');
const [canPass, setCanPass] = useState<boolean>(false);

useEffect(() => {
if (lightColor === 'green') setCanPass(true);
else setCanPass(false);
}, [lightColor]);
```

这里 canPass 不该是一个 state ,根本就是一个 computed value ,用 useMemo 才对:

```
const [lightColor, setLightColor] = useState<'red' | 'yellow' | 'green'>('red');
const canPass = useMemo(() => lightColor === 'green', [lightColor]);
```

大多数场合 useMemo 也是多余的,遇到性能问题再优化就可以:

```
canPass = lightColor === 'green';
```

所以我给 React 新人的建议都是:少用 useEffect ,如果遇到了必须 useEffect 的 case ,看看 ahooks 等库里有没有现成的 hook 。

importmeta

20

importmeta      2025 年 2 月 22 日

这个问题是 eslint 搞得, 其实也可以不用管, 我调用第三方函数的时候, 这个依赖列表还是保留空数组, 它报警告就报警告, 等熟练了, 知道到底怎么依赖的时候, 关掉这条 eslint 规则就行.

ZztGqk

21

ZztGqk      2025 年 2 月 22 日

react 的去年由 Dan 更新的新 doc 很详细的说,https://react.dev/learn/you-might-not-need-an-effect ,很多时候你只是需要一个新的值,而不是修改一个已有的值,由于 function 会被执行多次,所以这个概念相对常见,甚至在某些轻度转换的情况无需 memo ,至于使用 memo 或者 callback 来存值的概念我觉得更像 vue3 或者 solid 那种只执行一次的概念,更像是 computed 。不使用 memo 直接 const 一个新的值可以配合 react compiler 来帮你完成这种包装。另外随着项目的增长你可以需要 Jotai 或者 别的状态库,我觉得从 SPA (直接使用 vite + react router (非 Remix 版本,这里有点混乱,去年 Remix 和 React Router 合并了,导致现在 v7 有些部分为了支持 Server Componet 变得不再纯粹,可以参考 v6 的文档逐步过渡)过渡到 SSR 学习曲线会稍微舒服一些,毕竟我觉得 next 里的 server Compoent 的概念会阻碍初学者对于状态管理的认知...

ZztGqk

22

ZztGqk      2025 年 2 月 22 日

@X_Del 是的这种情况我觉得直接 const 一个新值就可以了,现在有 React Compiler ,Memo 直接让它自动去加就行了。

loveloki32

23

loveloki32      2025 年 2 月 26 日 via iPhone

21 楼的说得很不错。

不是所有的东西都需要做状态管理,如果数据量不大,你这个变量也不需要 memo ,直接 const 定义一个新变量即可。

另外补充一些:

1. 你可以一方面看官方文档,另外看下 Dan 的博客( https://overreacted.io ),里面讲了很多“react 思维方式”

2. 对于初学者来说先不要不学 react19 的服务端组件,这个会麻烦一点(不过这个会逼着你重新思考状态管理,另一个角度是好事),你用 nextjs 可能会大量时间在这个上面踩坑,如果发现这个上面花费时间有点多的话,可以用 vite 创建项目去学习。

3. 对于官方文档有问题也可以直接直接提 issue 或者 pr ,有的时候可能是文档翻译得不好导致你理解出了偏差(中文仓库: https://github.com/reactjs/zh-hans.react.dev

loveloki32

24

loveloki32      2025 年 2 月 26 日 via iPhone

另外不要忽略 eslint 的提示,一般来说都是代码逻辑有问题,可能需要重新思考下写法

loveloki32

25

loveloki32      2025 年 2 月 26 日

啊没发现打错字了。

先不要学 react19 的服务端组件,这个心智负担太重了