关于 react-compiler
面向启用 React Compiler 的 React 19+ 项目的编码技能,指导 Agent 避免不必要的手动记忆化,并在特定例外下保留它,还可审查编译器设置和 lint 问题。
主要功能
- 01默认避免手动记忆化
- 02按三类例外保留记忆化
- 03核查编译器和 lint 配置
- 04审查现有记忆化用法
- 05识别编译器跳过编译的情况
适用场景
- 01编写不含多余包装的 React 组件
- 02审查启用编译器项目中的记忆化
- 03审计前检查编译器和 lint 设置
- 04查找并修复阻碍编译的模式
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ saschb2b/ skills --skill react-compiler安装后在 Claude Code 中输入/react-compiler确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CARD.manifest.jsonCARD.mdCARD.md.sigstoreCARD.svgpermissions.yamlreferences/exceptions.mdindex.mdlint-setup.md详细介绍
React Compiler
规则
编译器负责记忆化。你不必。
在启用了编译器的任何 React 19+ 代码库中,默认不要添加 useMemo、useCallback 或 React.memo。编译器可以比人工编写的代码更精细地处理记忆化,而手动添加这些代码充其量只是噪音。这是 LLM 生成的 React 代码最常见的问题:任何 Agent 的 React 训练语料大多都来自编译器出现之前,因此默认输出往往会偏向手动记忆化。
编写 React 时的默认做法
直接编写组件:
function DashboardRow({ entity, onSelect }) {
const label = formatLabel(entity);
const total = entity.items.reduce((sum, i) => sum + i.value, 0);
return (
<Row onClick={() => onSelect(entity.id)}>
<Label>{label}</Label>
<Total>{total}</Total>
</Row>
);
}
不要这样写:
const DashboardRow = memo(({ entity, onSelect }) => {
const formatted = useMemo(() => ({ /* ... */ }), [entity]);
const handleClick = useCallback(() => onSelect(entity.id), [entity.id, onSelect]);
return /* ... */;
});
对于任何符合 React 规则的输入,编译器都会生成与第一种写法等效的代码。手动添加第二种写法只是噪音,还可能干扰编译器的分析。
仍需手动记忆化的三个例外情况
仅在以下情况保留手动 useMemo 或 useCallback:
- 为非 React 消费方保持引用标识。 将值传递给
addEventListener、IntersectionObserver、会自行进行===检查的第三方库,以及任何会保留引用的 React 之外的对象时。 - 编译器无法分析的高开销非渲染工作。 例如解析大型数据块、构建大型索引或调用高开销库。保留记忆化,并添加注释说明原因。
- 为保证正确性而必须保持稳定的 Effect 依赖项。 如果没有包装,某个依赖项会导致 Effect 每次渲染都触发,就保留它。
除这三种情况外,其他手动记忆化都应删除。
对现有代码库的审查工作流
- 确认已启用编译器。 检查
next.config(experimental.reactCompiler)、vite.config或babel.config(babel-plugin-react-compiler),或 Expo 和 TanStack Start 的框架默认配置。如果未启用,先建议启用。不要在未启用编译器的代码库中移除记忆化。 - 确认
eslint-plugin-react-hooks版本为 v6+。 编译器规则于 2025 年末从已弃用的eslint-plugin-react-compiler合并而来。 - 将 lint 规则提升为
error。recommended中的大多数规则级别为warn,这意味着静默跳过编译的情况不会导致 CI 失败。严格配置请参阅 lint-setup.md。 - 清理手动记忆化。 删除不符合上述三个例外情况的
useMemo、useCallback和React.memo。 - 运行 lint。逐步修复静默跳过。 静默跳过会层层传递:修复上游的跳过问题后,可能会暴露下游的第二个问题。首次运行会给出问题数量,后续运行才能反映真实情况。
- 追踪
"use no memo"指令。 每个指令都意味着性能可能骤降,且背后应有待办事项。定期通过 grep 统计数量,将其作为健康指标。
编译器静默退出编译的情况
有五种模式会导致周围的函数无法参与编译。严格配置后,上述 lint 规则会检测这些模式。完整列表、代码示例和修复方法请参阅 exceptions.md。
审查结果格式
file: <path>
findings:
- removed: <useMemo | useCallback | memo> @ <line>, compiler handles
- kept: <useMemo | useCallback> @ <line>, reason: <ref-identity | expensive | effect-dep>
silent bails detected:
- <pattern> @ <line>: <one-line fix>
来源
内容基于 The React Compiler at Eighteen Months。相关细节请参阅 exceptions.md 和 lint-setup.md。
评论
支持 Markdown