立即迁移到 Netlify

Netlify 宣布 Gatsby Cloud 的下一次迭代。 了解更多

快速刷新

Fast Refresh 是 Hot Reloading 的一种实现,并得到了 React 的全力支持。它取代了 react-hot-loader 等非官方解决方案。

通过 Fast Refresh,您的 React 组件代码的更改会立即在浏览器中更新,而不会丢失组件状态。如果您的代码有错误,浏览器视图将显示一个错误叠加层,其中包含有关出错内容的更多详细信息。对您的更改的这种直接反馈带来了更好的整体开发体验(DX)。

Fast Refresh 默认在 Gatsby 的开发服务器中启用,并且应在一秒内显示您的更改。

工作原理

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

错误恢复能力

Fast Refresh 集成善于捕获错误而不是静默失败。Gatsby 利用此机会向您展示一个自定义叠加层,以进一步解释错误及其解决办法。一旦错误得到解决,Fast Refresh 将从该状态恢复。叠加层将指示这是编译错误、GraphQL 错误、运行时错误还是 getServerData 错误。

Four error overlays from left to right, top to bottom: Compile error, GraphQL errors, runtime errors, and getServerData error

编译错误

编译错误源自 webpack,无法关闭。这些错误会阻止代码本身的编译,因此您需要修复它们才能看到页面。调试 HTML 构建指南在某些情况下也可能有所帮助。

GraphQL 错误

GraphQL 错误可能由于多种原因发生,最常见的原因是页面查询或静态查询内部出错。除了错误消息外,您还将收到一个错误 ID(例如 #85923),您可以使用它来扫描文档和互联网以获取更多信息。

运行时错误

如果运行时错误未在渲染期间发生,则组件状态将保留。但是,如果错误发生在渲染期间,React 将使用更新后的代码重新挂载您的应用程序。

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

getServerData 错误

这些错误源自您页面中的 getServerData 函数,并且无法关闭。在使用服务器端渲染 (SSR) 时,您的代码将在运行时运行,并显示在您已部署的网站上。您自己的代码可能存在故障,第三方请求(例如,到外部 API)也可能存在故障,因此在函数中添加错误处理是个好主意。

局限性

Fast Refresh 会尝试在编辑之间保留组件的本地 React 状态,但前提是这样做是安全的。有一些原因可能导致文件每次编辑时本地状态都会重置。

  • 类组件不保留本地状态。只有函数组件和 Hooks 会保留状态。
  • 您正在编辑的文件可能除了 React 组件外还有其他导出。Gatsby 默认包含一个 ESLint 规则来警告页面中存在此模式:页面模板只能导出一个默认导出(页面)和作为命名导出的 query
  • 匿名箭头函数,如 export default () => <div />,会导致 Fast Refresh 不保留本地组件状态。Gatsby 默认包含一个 ESLint 规则来警告此模式。
  • 有时一个文件会导出一个高阶组件的执行结果,例如 HOC(WrappedComponent)。如果返回的组件是类或小写字母开头,状态将会重置。
  • 小写字母开头的组件,如 function example() {},会导致 Fast Refresh 不保留本地组件状态。组件和 HOC 必须使用PascalCase

提示

  • 有时您想强制重置状态并重新挂载组件。例如,当您调整仅在挂载时发生的动画时,这会很有用。要做到这一点,您可以在您正在编辑的文件中的任何位置添加 // @refresh reset。此指令仅限于文件,并指示 Fast Refresh 在每次编辑时重新挂载该文件中定义的组件。

React Hooks

在可能的情况下,Fast Refresh 会尝试在编辑之间保留组件的状态。特别是,useStateuseRef 会保留它们之前的值,只要您不更改它们的参数或 Hooks 调用顺序。

带有依赖项的 Hooks — 例如 useEffectuseMemouseCallback — 在 Fast Refresh 期间始终会更新。在 Fast Refresh 发生时,它们的依赖项列表将被忽略。

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

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

立即开始构建,在 Netlify!
在 GitHub 上编辑此页面
©2025Gatsby, Inc.