调试和故障排除

本指南可帮助你识别和修复使用 React Compiler 时遇到的问题。了解如何调试编译问题并解决常见问题。

¥This guide helps you identify and fix issues when using React Compiler. Learn how to debug compilation problems and resolve common issues.

你将学习到

  • 编译器错误和运行时问题之间的区别

    ¥The difference between compiler errors and runtime issues

  • 导致编译中断的常见模式

    ¥Common patterns that break compilation

  • 逐步调试工作流程

    ¥Step-by-step debugging workflow

了解编译器行为

¥Understanding Compiler Behavior

React Compiler 旨在处理遵循 React 的规则 的代码。当遇到可能违反这些规则的代码时,它会安全地跳过优化,而不会冒险改变应用的行为。

¥React Compiler is designed to handle code that follows the Rules of React. When it encounters code that might break these rules, it safely skips optimization rather than risk changing your app’s behavior.

编译器错误与运行时问题

¥Compiler Errors vs Runtime Issues

编译器错误发生在构建时,并阻止你的代码编译。这些方法很少见,因为编译器的设计初衷是跳过有问题的代码,而不是导致编译失败。

¥Compiler errors occur at build time and prevent your code from compiling. These are rare because the compiler is designed to skip problematic code rather than fail.

当编译后的代码行为与预期不同时,就会出现运行时问题。大多数情况下,如果你遇到 React 编译器的问题,那都是运行时问题。这种情况通常发生在你的代码以编译器无法检测到的细微方式违反了 React 规则,并且编译器错误地编译了它本应跳过的组件时。

¥Runtime issues occur when compiled code behaves differently than expected. Most of the time, if you encounter an issue with React Compiler, it’s a runtime issue. This typically happens when your code violates the Rules of React in subtle ways that the compiler couldn’t detect, and the compiler mistakenly compiled a component it should have skipped.

调试运行时问题时,请集中精力查找受影响组件中 ESLint 规则未检测到的 React 规则违规。编译器依赖于你的代码遵循这些规则,当这些规则以无法检测到的方式被破坏时,就会出现运行时问题。

¥When debugging runtime issues, focus your efforts on finding Rules of React violations in the affected components that were not detected by the ESLint rule. The compiler relies on your code following these rules, and when they’re broken in ways it can’t detect, that’s when runtime problems occur.

常见破坏模式

¥Common Breaking Patterns

React Compiler 可能导致你的应用崩溃的主要原因之一是,你的代码依赖于 memoization 来确保正确性。这意味着你的应用依赖于被记忆的特定值才能正常工作。由于编译器的记忆方式可能与你的手动方法不同,这可能会导致意外行为,例如效果过度触发、无限循环或丢失更新。

¥One of the main ways React Compiler can break your app is if your code was written to rely on memoization for correctness. This means your app depends on specific values being memoized to work properly. Since the compiler may memoize differently than your manual approach, this can lead to unexpected behavior like effects over-firing, infinite loops, or missing updates.

发生这种情况的常见场景:

¥Common scenarios where this occurs:

  • 依赖于引用相等的效果 - 当效果依赖于对象或数组在渲染过程中保持相同引用时

    ¥Effects that rely on referential equality - When effects depend on objects or arrays maintaining the same reference across renders

  • 需要稳定引用的依赖数组 - 当不稳定的依赖导致副作用过于频繁地触发或创建无限循环时

    ¥Dependency arrays that need stable references - When unstable dependencies cause effects to fire too often or create infinite loops

  • 基于引用检查的条件逻辑 - 当代码使用引用相等性检查进行缓存或优化时

    ¥Conditional logic based on reference checks - When code uses referential equality checks for caching or optimization

调试工作流程

¥Debugging Workflow

遇到问题时请遵循以下步骤:

¥Follow these steps when you encounter issues:

编译器构建错误

¥Compiler Build Errors

如果你遇到编译器错误,导致构建意外中断,这很可能是编译器中的一个错误。使用以下方式向 facebook/react 代码库报告:

¥If you encounter a compiler error that unexpectedly breaks your build, this is likely a bug in the compiler. Report it to the facebook/react repository with:

  • 错误消息

    ¥The error message

  • 导致错误的代码

    ¥The code that caused the error

  • 你的 React 和编译器版本

    ¥Your React and compiler versions

运行时问题

¥Runtime Issues

对于运行时行为问题:

¥For runtime behavior issues:

1. 暂时禁用编译

¥ Temporarily Disable Compilation

使用 "use no memo" 来隔离问题是否与编译器相关:

¥Use "use no memo" to isolate whether an issue is compiler-related:

function ProblematicComponent() {
"use no memo"; // Skip compilation for this component
// ... rest of component
}

如果问题消失,则可能与 React 规则违规有关。

¥If the issue disappears, it’s likely related to a Rules of React violation.

你还可以尝试从有问题的组件中删除手动记忆(useMemo、useCallback、memo),以验证你的应用在没有任何记忆的情况下正常运行。如果移除所有 memoization 后 bug 仍然存在,则说明存在 React 规则违规,需要修复。

¥You can also try removing manual memoization (useMemo, useCallback, memo) from the problematic component to verify that your app works correctly without any memoization. If the bug still occurs when all memoization is removed, you have a Rules of React violation that needs to be fixed.

2. 逐步修复问题

¥ Fix Issues Step by Step

  1. 识别根本原因(通常是记忆化以确保正确性)

    ¥Identify the root cause (often memoization-for-correctness)

  2. 每次修复后进行测试

    ¥Test after each fix

  3. 修复后删除 "use no memo"

    ¥Remove "use no memo" once fixed

  4. 验证组件在 React DevTools 中是否显示 ✨ 标记

    ¥Verify the component shows the ✨ badge in React DevTools

报告编译器错误

¥Reporting Compiler Bugs

如果你认为发现了编译器 bug:

¥If you believe you’ve found a compiler bug:

  1. 验证这不违反 React 规则 - 使用 ESLint 检查

    ¥Verify it’s not a Rules of React violation - Check with ESLint

  2. 创建最小复现 - 在一个小示例中隔离问题

    ¥Create a minimal reproduction - Isolate the issue in a small example

  3. 不使用编译器进行测试 - 确认问题仅发生在编译阶段

    ¥Test without the compiler - Confirm the issue only occurs with compilation

  4. 提交 issue

    ¥File an issue:

    • React 和编译器版本

      ¥React and compiler versions

    • 最小化复现代码

      ¥Minimal reproduction code

    • 预期行为与实际行为

      ¥Expected vs actual behavior

    • 任何错误消息

      ¥Any error messages

下一步

¥Next Steps