随着大语言模型在代码生成领域的广泛应用,越来越多的开发者开始借助 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、空字符串时,!!0 为 false 但 0 && 依然可能渲染 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 可能忘记 preventDefault 或 stopPropagation。
坏味道:
<form onSubmit={handleSubmit}> // 页面会刷新
推荐写法:
const handleSubmit = (e) => {
e.preventDefault();
// 处理逻辑
};
<form onSubmit={handleSubmit}>
类似地,a 标签的 onClick 中若没有 e.preventDefault(),页面仍会跳转。合并前请逐一检查事件处理函数,确保副作用行为符合预期。
结语
AI 生成的 React 组件在“可运行”层面已经相当出色,但距离“可维护、高性能”仍有距离。上述 6 个坏味道是日常代码审查中最常见的问题,每一个都对应着 React 社区经过多年实践总结出的最佳实践。开发者在使用 AI 辅助时,不妨将这篇清单作为合并前的自检表,逐项排查。毕竟,AI 是加速器,而最终对代码质量负责的,依然是工程师本身。