Skip to content

NextJS中文文档 - Fast Refresh

快速刷新是一种集成到 Next.js 中的 React 功能,它允许你在保存文件更改时实时重新加载浏览器页面,同时保持临时的客户端状态。它在所有 9.4 或更新版本的 Next.js 应用程序中默认启用。启用快速刷新后,大多数编辑应该在一秒内可见。

工作原理

  • 如果你编辑的文件仅导出 React 组件,快速刷新将只更新该文件的代码,并重新渲染你的组件。你可以编辑该文件中的任何内容,包括样式、渲染逻辑、事件处理程序或副作用。
  • 如果你编辑的文件导出的不是 React 组件,快速刷新将重新运行该文件以及导入它的其他文件。所以如果 Button.jsModal.js 都导入了 theme.js,编辑 theme.js 将更新这两个组件。
  • 最后,如果你编辑的文件被 React 树之外的文件导入,快速刷新将回退到执行完全重新加载。你可能有一个文件渲染了 React 组件但同时也导出了一个被非 React 组件导入的值。例如,也许你的组件还导出了一个常量,而一个非 React 工具文件导入了它。在这种情况下,考虑将常量迁移到一个单独的文件中,并在两个文件中导入它。这将重新启用快速刷新功能。其他情况通常可以通过类似的方式解决。

错误恢复能力

语法错误

如果你在开发过程中出现语法错误,你可以修复它并再次保存文件。错误将自动消失,因此你无需重新加载应用程序。你不会丢失组件状态

运行时错误

如果你犯了一个导致组件内部运行时错误的错误,你将看到一个上下文覆盖层。修复错误将自动关闭覆盖层,而不重新加载应用程序。

如果错误不是在渲染过程中发生的,组件状态将被保留。如果错误是在渲染过程中发生的,React 将使用更新后的代码重新挂载你的应用程序。

如果你的应用程序中有错误边界(这对于生产环境中的优雅失败是个好主意),它们将在渲染错误后的下一次编辑时重试渲染。这意味着拥有错误边界可以防止你总是被重置到根应用程序状态。但是,请记住,错误边界不应该过于细粒度。它们在生产环境中被 React 使用,应该始终有意设计。

限制

快速刷新尝试保留你正在编辑的组件中的本地 React 状态,但前提是这样做是安全的。以下是一些可能导致你看到本地状态在每次编辑文件时被重置的原因:

  • 类组件的本地状态不会被保留(只有函数组件和 Hooks 会保留状态)。
  • 你正在编辑的文件可能除了 React 组件外还有其他导出。
  • 有时,一个文件会导出调用高阶组件的结果,如 HOC(WrappedComponent)。如果返回的组件是一个类,其状态将被重置。
  • 匿名箭头函数如 export default () => <div />; 会导致快速刷新不保留本地组件状态。对于大型代码库,你可以使用我们的 name-default-component codemod

随着你的代码库更多地转向函数组件和 Hooks,你可以期望在更多情况下保留状态。

提示

  • 默认情况下,快速刷新会保留函数组件(和 Hooks)中的 React 本地状态。
  • 有时你可能想强制状态重置,并重新挂载组件。例如,如果你正在调整只在挂载时发生的动画,这可能会很方便。为此,你可以在正在编辑的文件中的任何位置添加 // @refresh reset。这个指令是针对该文件的本地指令,它指示快速刷新在每次编辑时重新挂载该文件中定义的组件。
  • 你可以在开发过程中编辑的组件中放置 console.logdebugger;
  • 记住导入是区分大小写的。当你的导入与实际文件名不匹配时,快速刷新和完全刷新都可能失败。 例如,'./header''./Header'

快速刷新和 Hooks

在可能的情况下,快速刷新尝试在编辑之间保留组件的状态。特别是,只要你不改变它们的参数或 Hook 调用的顺序,useStateuseRef 就会保留它们之前的值。

具有依赖项的 Hooks——如 useEffectuseMemouseCallback——在快速刷新期间总是会更新。在快速刷新发生时,它们的依赖项列表将被忽略。

例如,当你将 useMemo(() => x * 2, [x]) 编辑为 useMemo(() => x * 10, [x]) 时,即使 x(依赖项)没有改变,它也会重新运行。如果 React 不这样做,你的编辑就不会反映在屏幕上!

有时,这可能会导致意外结果。例如,即使是一个具有空依赖数组的 useEffect 也会在快速刷新期间重新运行一次。

然而,编写能够适应 useEffect 偶尔重新运行的代码是一种良好的实践,即使没有快速刷新也是如此。这将使你更容易在以后向其添加新的依赖项,并且这也是由React 严格模式强制执行的,我们强烈建议启用它。

🎉有任何问题,欢迎联系我

WeChat QR Code
WeChat
QQ QR Code
QQ

赣ICP备2023003243号