跳至主内容

快速刷新(Fast Refresh)

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

快速刷新(Fast Refresh)是 React Native 的一项功能,能让您在修改 React 组件时获得近乎即时的反馈。该功能默认启用,您可以在 React Native 开发者菜单 中切换"启用快速刷新"选项。启用后,大多数修改都能在 1-2 秒内生效。

工作原理

  • 当您修改仅导出 React 组件的模块时,快速刷新会单独更新该模块代码并重新渲染组件。您可以修改文件内的任意内容,包括样式、渲染逻辑、事件处理函数或副作用。

  • 当您修改包含非 React 组件导出的模块时,快速刷新会重新执行该模块及其所有导入模块。例如当 Button.jsModal.js 都导入了 Theme.js,修改 Theme.js 会同时更新这两个组件。

  • 最后,当您修改的文件被 React 树之外的模块导入时,快速刷新会回退到完全重新加载。这种情况常见于:某个文件既导出了 React 组件,又导出了被非 React 组件引用的值(例如导出的常量被工具模块引用)。解决方案是将共享值抽离到独立文件再分别导入,这样就能重新启用快速刷新。其他类似情况也可参照此方法解决。

错误恢复能力

如果在快速刷新会话中出现语法错误,修复后重新保存文件即可。红色错误框(redbox)会消失,包含语法错误的模块会被阻止运行,您无需重新加载整个应用。

如果出现模块初始化时的运行时错误(例如误将 StyleSheet.create 写成 Style.create),修复错误后快速刷新会话会自动继续。红色错误框消失,模块将完成更新。

如果修改导致组件内部发生运行时错误,修复后快速刷新会话同样会继续。此时 React 会使用更新后的代码重新挂载您的应用。

应用中配置的错误边界(对生产环境优雅降级非常重要)会在下次编辑时重试渲染。因此合理使用错误边界可避免应用总是回退到根页面。但需注意:错误边界不宜过度细分,它们在 React 生产环境中同样适用,应谨慎设计。

局限性

快速刷新会尝试保留您所编辑组件的 React 本地状态(local state),但仅在安全时生效。以下是编辑文件时状态被重置的常见原因:

  • 类组件(class components)的状态不会被保留(仅函数组件和 Hooks 能保留状态)

  • 您编辑的模块可能包含除 React 组件外的其他导出

  • 当模块导出高阶组件调用结果时(例如 createNavigationContainer(MyScreen)),若返回的是类组件,状态将被重置

长期来看,随着代码库向函数组件和 Hooks 迁移,状态保留的适用范围将逐步扩大。

使用技巧

  • 快速刷新默认会保留函数组件(及 Hooks)的 React 本地状态

  • 有时你可能需要强制重置状态并重新挂载组件。例如,当调整仅在挂载时执行的动画效果时就很有用。要实现这一点,只需在编辑的文件任意位置添加 // @refresh reset 指令。该指令仅作用于当前文件,会指示 Fast Refresh 在每次编辑后重新挂载该文件中定义的组件。

Fast Refresh 与 Hooks

在可能的情况下,Fast Refresh 会尝试保留组件状态。具体而言,只要不修改参数或 Hooks 的调用顺序,useStateuseRef 都会保留之前的值。

具有依赖项的 Hooks(如 useEffectuseMemouseCallback)在 Fast Refresh 期间始终会更新。此时它们的依赖项列表将被忽略。

例如,当你将 useMemo(() => x * 2, [x]) 改为 useMemo(() => x * 10, [x]) 时,即使依赖项 x 未变化也会重新执行。如果 React 不这样做,你的修改就无法在屏幕上体现!

这有时可能导致意外结果。例如,即使依赖项数组为空的 useEffect 在 Fast Refresh 期间也会重新执行一次。但编写能够弹性应对 useEffect 偶尔重新执行的代码本身就是良好实践,与 Fast Refresh 无关。这能为你后续添加新依赖项提供便利。