打开网易新闻 查看精彩图片

GitHub Copilot每10秒生成一次代码,但没人统计过其中有多少在"看似正确"的瞬间已经埋好了雷。React开发者Avery最近扒出了一组高频模式——AI把"计算值"当成"状态值"存进useEffect,代码能跑,逻辑全歪。

那个让组件渲染两次的"标准写法"

那个让组件渲染两次的"标准写法"

打开任意一个AI参与过的React项目,你大概率会看到这个模式:

const [total, setTotal] = useState(0) useEffect(() => { setTotal(items.reduce((sum, i) => sum + i.price, 0)) }, [items])

Copilot输出这段代码时毫无犹豫。没有警告,没有红线,只有一种"这很合理"的平静。但问题恰恰藏在平静里——total根本不是状态,它是一次计算的结果。items变一次,total就被强制重新算一次,中间还要经过useState的setter触发额外渲染。

组件渲染了两次。状态永远慢半拍。一个毫无存在必要的useEffect,只是因为AI没见过"不该这么写"的规则。

打开网易新闻 查看精彩图片

AI的"肌肉记忆"是怎么形成的

AI的"肌肉记忆"是怎么形成的

Copilot不是不懂React,它是太懂"看起来像React的代码"长什么样。它的训练数据里有成千上万条useState配useEffect的组合,于是遇到任何需要"某个值"的场景,默认伸手就是这对组合拳。

它不理解"派生状态"(derived state)这个概念。不会问"这东西该存还是该算",只会生成"看起来 plausible 的代码"。

而plausible和correct之间,隔着整个调试周期的距离。

正确的写法其实更简单:

const total = items.reduce((sum, i) => sum + i.price, 0)

打开网易新闻 查看精彩图片

没有useState,没有useEffect,每次渲染直接算。一次渲染,单一数据源,零冗余状态。代码行数少了,心智负担也少了,但AI不会主动给你这个——除非你的prompt里明确写了"禁止useEffect处理同步计算"。

useEffect滥用正在批量制造"技术债惊喜"

useEffect滥用正在批量制造"技术债惊喜"

Avery在排查中发现,useEffect的误用是AI生成React代码里最高频的陷阱之一。不是因为开发者不懂,而是因为Copilot"伸手就来"——派生状态要用,同步逻辑要用,根本不该是effect的东西它全往里塞。

每一个AI没有明确约束的领域,都是它即兴发挥的空间。而即兴的useEffect逻辑在真实代码库里会指数级叠加:A组件的effect触发B组件重渲染,B的effect又改C的状态,调试时你看到的永远是"最后一次渲染的结果",而不是"为什么会多渲染三次"。

Avery为此整理了一份20项检查清单,专门用来识别这类结构性弱点。不是教你写prompt,而是让你在跑AI生成的代码之前,先扫一遍雷区。

同一套Copilot,有人用它写出一堆定时炸弹,有人用它稳定输出。差距不在工具,在规则。

你最近一次review AI代码时,有没有发现某个useEffect其实根本不该存在?