请教一个关于 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这个规则吗?
多个 state 有时候是可以合并成一个的,某些情况可以解决 useEffect 依赖报 warning 。
明确知道自己逻辑正确的时候,忽略 warning 就好了,react 写多了就习惯了
如果你连 currentChatId 都不想加,说明 currentChatId 本身是常量或者不更新的值,你应该使用 useMemo 包裹起来,避免重复计算,eslint 的规则不能关闭,他确实能反映依赖的问题,但是 ahooks 是必须使用的,作为 react 的 hooks 包装,能节省很多代码,另外你这个写法是不能够优化,currentChatTitle 在什么时候更新?初始化更新应该放在 useMount 上,事件触发应该放在函数里,这种情况的副作用不多见。
这样还能节约一次重绘,useEffect 那种 set 状态相当于 中括号里的变量变化一次重绘,useEffect 触发完因为 set 了 state 又触发一次重绘。useMemo 则可以是 一次绘制里面直接根据中括号里面的值,这一轮绘制就给变化的结果返回去。