|
| 1 | +--- |
| 2 | +description: |
| 3 | + Next.js' Fast Refresh is a new hot reloading experience that gives you |
| 4 | + instantaneous feedback on edits made to your React components. |
| 5 | +--- |
| 6 | + |
| 7 | +# Fast Refresh |
| 8 | + |
| 9 | +Fast Refresh is a Next.js feature that that gives you instantaneous feedback on |
| 10 | +edits made to your React components. Fast Refresh is enabled by default in all |
| 11 | +Next.js applications on **9.4 or newer**. With Next.js Fast Refresh enabled, |
| 12 | +most edits should be visible within a second, **without losing component |
| 13 | +state**. |
| 14 | + |
| 15 | +## How It Works |
| 16 | + |
| 17 | +- If you edit a file that **only exports React component(s)**, Fast Refresh will |
| 18 | + update the code only for that file, and re-render your component. You can edit |
| 19 | + anything in that file, including styles, rendering logic, event handlers, or |
| 20 | + effects. |
| 21 | +- If you edit a file with exports that _aren't_ React components, Fast Refresh |
| 22 | + will re-run both that file, and the other files importing it. So if both |
| 23 | + `Button.js` and `Modal.js` import `theme.js`, editing `theme.js` will update |
| 24 | + both components. |
| 25 | +- Finally, if you **edit a file** that's **imported by files outside of the |
| 26 | + React tree**, Fast Refresh **will fall back to doing a full reload**. You |
| 27 | + might have a file which renders a React component but also exports a value |
| 28 | + that is imported by a **non-React component**. For example, maybe your |
| 29 | + component also exports a constant, and a non-React utility file imports it. In |
| 30 | + that case, consider migrating the constant to a separate file and importing it |
| 31 | + into both files. This will re-enable Fast Refresh to work. Other cases can |
| 32 | + usually be solved in a similar way. |
| 33 | + |
| 34 | +## Error Resilience |
| 35 | + |
| 36 | +### Syntax Errors |
| 37 | + |
| 38 | +If you make a syntax error during development, you can fix it and save the file |
| 39 | +again. The error will disappear automatically, so you won't need to reload the |
| 40 | +app. **You will not lose component state**. |
| 41 | + |
| 42 | +### Runtime Errors |
| 43 | + |
| 44 | +If you make a mistake that leads to a runtime error inside your component, |
| 45 | +you'll be greeted with a contextual overlay. Fixing the error will automatically |
| 46 | +dismiss the overlay, without reloading the app. |
| 47 | + |
| 48 | +Component state will be retained if the error did not occur during rendering. If |
| 49 | +the error did occur during rendering, React will remount your application using |
| 50 | +the updated code. |
| 51 | + |
| 52 | +If you have [error boundaries](https://reactjs.org/docs/error-boundaries.html) |
| 53 | +in your app (which is a good idea for graceful failures in production), they |
| 54 | +will retry rendering on the next edit after a rendering error. This means having |
| 55 | +an error boundary can prevent you from always getting reset to the root app |
| 56 | +state. However, keep in mind that error boundaries shouldn't be _too_ granular. |
| 57 | +They are used by React in production, and should always be designed |
| 58 | +intentionally. |
| 59 | + |
| 60 | +## Limitations |
| 61 | + |
| 62 | +Fast Refresh tries to preserve local React state in the component you're |
| 63 | +editing, but only if it's safe to do so. Here's a few reasons why you might see |
| 64 | +local state being reset on every edit to a file: |
| 65 | + |
| 66 | +- Local state is not preserved for class components (only function components |
| 67 | + and Hooks preserve state). |
| 68 | +- The file you're editing might have _other_ exports in addition to a React |
| 69 | + component. |
| 70 | +- Sometimes, a file would export the result of calling higher-order component |
| 71 | + like `higherOrderComponent(WrappedComponent)`. If the returned component is a |
| 72 | + class, state will be reset. |
| 73 | + |
| 74 | +As more of your codebase moves to function components and Hooks, you can expect |
| 75 | +state to be preserved in more cases. |
| 76 | + |
| 77 | +## Tips |
| 78 | + |
| 79 | +- Fast Refresh preserves React local state in function components (and Hooks) by |
| 80 | + default. |
| 81 | +- Sometimes you might want to _force_ the state to be reset, and a component to |
| 82 | + be remounted. For example, this can be handy if you're tweaking an animation |
| 83 | + that only happens on mount. To do this, you can add `// @refresh reset` |
| 84 | + anywhere in the file you're editing. This directive is local to the file, and |
| 85 | + instructs Fast Refresh to remount components defined in that file on every |
| 86 | + edit. |
| 87 | +- You can put `console.log` or `debugger;` into the components you edit during |
| 88 | + development. |
| 89 | + |
| 90 | +## Fast Refresh and Hooks |
| 91 | + |
| 92 | +When possible, Fast Refresh attempts to preserve the state of your component |
| 93 | +between edits. In particular, `useState` and `useRef` preserve their previous |
| 94 | +values as long as you don't change their arguments or the order of the Hook |
| 95 | +calls. |
| 96 | + |
| 97 | +Hooks with dependencies—such as `useEffect`, `useMemo`, and `useCallback`—will |
| 98 | +_always_ update during Fast Refresh. Their list of dependencies will be ignored |
| 99 | +while Fast Refresh is happening. |
| 100 | + |
| 101 | +For example, when you edit `useMemo(() => x * 2, [x])` to |
| 102 | +`useMemo(() => x * 10, [x])`, it will re-run even though `x` (the dependency) |
| 103 | +has not changed. If React didn't do that, your edit wouldn't reflect on the |
| 104 | +screen! |
| 105 | + |
| 106 | +Sometimes, this can lead to unexpected results. For example, even a `useEffect` |
| 107 | +with an empty array of dependencies would still re-run once during Fast Refresh. |
| 108 | +However, writing code resilient to occasional re-running of `useEffect` is a |
| 109 | +good practice even without Fast Refresh. This makes it easier for you to later |
| 110 | +introduce new dependencies to it. |
0 commit comments