You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| MDX routes | ✅ | ❓ | ⏳ |[Supported with some deprecations.][supported-with-some-deprecations]|
@@ -494,10 +494,92 @@ If you want to reuse values across routes, stick them in their own non-route mod
494
494
exportconst myValue ="some value";
495
495
```
496
496
497
-
#### Adding and Removing Hooks
497
+
#### Changing Hooks
498
498
499
499
React Fast Refresh cannot track changes for a component when hooks are being added or removed from it, causing full reloads just for the next render. After the hooks have been updated, changes should result in hot updates again. For example, if you add [`useLoaderData`][use_loader_data] to your component, you may lose state local to that component for that render.
500
500
501
+
Additionally, if you are destructuring a hook's return value, React Fast Refresh will not be able to preserve state for the component if the destructured key is removed or renamed.
502
+
For example:
503
+
504
+
```tsx
505
+
exportconst loader = () => {
506
+
returnjson({ stuff: "some things" });
507
+
};
508
+
509
+
exportdefaultfunction Component() {
510
+
const { stuff } =useLoaderData<typeofloader>();
511
+
return (
512
+
<div>
513
+
<input />
514
+
<p>{stuff}</p>
515
+
</div>
516
+
);
517
+
}
518
+
```
519
+
520
+
If you change the key `stuff` to `things`:
521
+
522
+
```diff
523
+
export const loader = () => {
524
+
- return json({ stuff: "some things" })
525
+
+ return json({ things: "some things" })
526
+
}
527
+
528
+
export default Component() {
529
+
- let { stuff } = useLoaderData<typeof loader>()
530
+
+ let { things } = useLoaderData<typeof loader>()
531
+
return (
532
+
<div>
533
+
<input />
534
+
- <p>{stuff}</p>
535
+
+ <p>{things}</p>
536
+
</div>
537
+
)
538
+
}
539
+
```
540
+
541
+
then React Fast Refresh will not be able to preserve state `<input />` ❌.
542
+
543
+
As a workaround, you could refrain from destructuring and instead use the hook's return value directly:
544
+
545
+
```tsx
546
+
exportconst loader = () => {
547
+
returnjson({ stuff: "some things" });
548
+
};
549
+
550
+
exportdefaultfunction Component() {
551
+
const data =useLoaderData<typeofloader>();
552
+
return (
553
+
<div>
554
+
<input />
555
+
<p>{data.stuff}</p>
556
+
</div>
557
+
);
558
+
}
559
+
```
560
+
561
+
Now if you change the key `stuff` to `things`:
562
+
563
+
```diff
564
+
export const loader = () => {
565
+
- return json({ things: "some things" })
566
+
+ return json({ things: "some things" })
567
+
}
568
+
569
+
export default Component() {
570
+
let data = useLoaderData<typeof loader>()
571
+
return (
572
+
<div>
573
+
<input />
574
+
- <p>{data.stuff}</p>
575
+
+ <p>{data.things}</p>
576
+
</div>
577
+
)
578
+
}
579
+
```
580
+
581
+
then React Fast Refresh will preserve state for the `<input />`, though you may need to use [component keys][component-keys] as described in the next section if the stateful element (e.g. `<input />`) is a sibling of the changed element.
582
+
501
583
#### Component Keys
502
584
503
585
In some cases, React cannot distinguish between existing components being changed and new components being added. [React needs `key`s][react_keys] to disambiguate these cases and track changes when sibling elements are modified.
@@ -560,3 +642,4 @@ We're definitely late to the Vite party, but we're excited to be here now!
0 commit comments