随着大语言模型在代码生成领域的广泛应用,越来越多的开发者开始借助 AI 辅助编写 React 组件。然而,AI 生成的代码虽然“能跑”,却常常隐藏着不易察觉的“坏味道”——这些写法在功能上看似正确,但在性能、可维护性、可读性上却埋下了隐患。资深前端工程师在合并 AI 生成的代码前,通常会重点检查以下 6 种常见问题,每个问题我们都给出了清晰的正反代码对比,帮助开发者快速甄别。

一、滥用 useEffect 处理纯计算逻辑

AI 模型容易将一切副作用都塞进 useEffect,哪怕只是简单的数据转换。例如,从 props 中提取并格式化日期:

坏味道(AI 常见输出):

useEffect(() => {
  const formatted = formatDate(props.rawDate);
  setFormattedDate(formatted);
}, [props.rawDate]);

推荐写法

const formattedDate = useMemo(() => formatDate(props.rawDate), [props.rawDate]);

直接用 useMemo 推导派生状态,既减少了状态更新次数,又避免了不必要的重新渲染。合并前务必确认:useEffect 里是否真的需要执行副作用?

二、组件内部直接定义大函数对象

AI 有时会在组件 render 内部定义内联函数,导致每次渲染都创建新函数引用,破坏 React.memo 的缓存效果。

坏味道

const MyComponent = () => {
  const handleClick = () => { /* 复杂逻辑 */ };
  return <Child onClick={handleClick} />;
};

推荐写法

const MyComponent = () => {
  const handleClick = useCallback(() => { /* 复杂逻辑 */ }, []);
  return <Child onClick={handleClick} />;
};

使用 useCallback 稳定函数引用,尤其在子组件经过 React.memo 优化时,这一改动能显著减少不必要的子组件更新。

三、错误使用数组索引作为 key

列表渲染时,AI 常直接使用 index 作为 key,这在数据变化时会导致组件状态错乱。

坏味道

items.map((item, index) => <Item key={index} />);

推荐写法

items.map((item) => <Item key={item.id} />);

即使 AI 给出的 items 看起来不会变,也应改用唯一标识符。合并前检查所有 map 循环,确保 key 稳定且唯一。

四、过度使用 !! 进行布尔转换

AI 在条件渲染中爱用双感叹号强制转布尔,虽无性能问题,但降低代码可读性。

坏味道

{!!items.length && <List />}

推荐写法

{items.length > 0 && <List />}
// 或
{items.length !== 0 && <List />}

显式比较能直接表达意图,减少后续维护者的误解。尤其当条件涉及 0、空字符串时,!!0false0 && 依然可能渲染 0,而严格比较能彻底避免这类陷阱。

五、在组件顶层滥用 useState 存储可计算值

比如将 props 传入的值直接复制到 state 中,然后再手动同步。

坏味道

const [user, setUser] = useState(props.user);
useEffect(() => { setUser(props.user); }, [props.user]);

推荐写法

const user = props.user; // 直接使用 props

派生状态应该直接从 props 推导,而不是通过 state 同步。除非你需要对初始值进行修改(如表单编辑),否则应避免这种“双源”模式。AI 生成的此类代码极易导致状态不同步和无限循环。

六、忽略事件冒泡与默认行为

处理表单提交或链接点击时,AI 可能忘记 preventDefaultstopPropagation

坏味道

<form onSubmit={handleSubmit}> // 页面会刷新

推荐写法

const handleSubmit = (e) => {
  e.preventDefault();
  // 处理逻辑
};
<form onSubmit={handleSubmit}>

类似地,a 标签的 onClick 中若没有 e.preventDefault(),页面仍会跳转。合并前请逐一检查事件处理函数,确保副作用行为符合预期。


结语

AI 生成的 React 组件在“可运行”层面已经相当出色,但距离“可维护、高性能”仍有距离。上述 6 个坏味道是日常代码审查中最常见的问题,每一个都对应着 React 社区经过多年实践总结出的最佳实践。开发者在使用 AI 辅助时,不妨将这篇清单作为合并前的自检表,逐项排查。毕竟,AI 是加速器,而最终对代码质量负责的,依然是工程师本身。