Skip to content

Commit

Permalink
Add unstable_flushSync option (#11005)
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 authored Nov 13, 2023
1 parent fe066bd commit 1193ae5
Show file tree
Hide file tree
Showing 13 changed files with 747 additions and 106 deletions.
5 changes: 5 additions & 0 deletions .changeset/flush-sync-router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/router": minor
---

Add `unstable_flushSync` option to `router.navigate` and `router.fetch` to tell the React Router layer to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates
6 changes: 6 additions & 0 deletions .changeset/flush-sync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"react-router-dom": minor
"react-router": minor
---

Add `unstable_flushSync` option to `useNavigate`/`useSumbit`/`fetcher.load`/`fetcher.submit` to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates
14 changes: 12 additions & 2 deletions docs/hooks/use-fetcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function SomeComponent() {

## Methods

## `fetcher.load()`
### `fetcher.load(href, options)`

Loads data from a route loader.

Expand All @@ -133,7 +133,15 @@ If you find yourself calling this function inside of click handlers, you can pro

<docs-info>Any `fetcher.load` calls that are active on the page will be re-executed as part of revalidation (either after a navigation submission, another fetcher submission, or a `useRevalidator()` call)</docs-info>

## `fetcher.submit()`
#### `options.unstable_flushSync`

The `unstable_flushSync` option tells React Router DOM to wrap the initial state update for this `fetcher.load` in a [`ReactDOM.flushSync`][flush-sync] call instead of the default [`React.startTransition`][start-transition]. This allows you to perform synchronous DOM actions immediately after the update is flushed to the DOM.

<docs-warning>`ReactDOM.flushSync` de-optimizes React and can hurt the performance of your app.</docs-warning>

<docs-warning>Please note that this API is marked unstable and may be subject to breaking changes without a major release</docs-warning>

### `fetcher.submit()`

The imperative version of `<fetcher.Form>`. If a user interaction should initiate the fetch, you should use `<fetcher.Form>`. But if you, the programmer are initiating the fetch (not in response to a user clicking a button, etc.), then use this function.

Expand Down Expand Up @@ -279,3 +287,5 @@ fetcher.formMethod; // "post"
[api-development-strategy]: ../guides/api-development-strategy
[use-submit]: ./use-submit
[use-fetchers]: ./use-fetchers
[flush-sync]: https://react.dev/reference/react-dom/flushSync
[start-transition]: https://react.dev/reference/react/startTransition
14 changes: 14 additions & 0 deletions docs/hooks/use-navigate.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ interface NavigateOptions {
state?: any;
preventScrollReset?: boolean;
relative?: RelativeRoutingType;
unstable_flushSync?: boolean;
unstable_viewTransition?: boolean;
}

type RelativeRoutingType = "route" | "path";
Expand Down Expand Up @@ -85,6 +87,16 @@ function EditContact() {
}
```

## `options.unstable_flushSync`

The `unstable_flushSync` option tells React Router DOM to wrap the initial state update for this navigation in a [`ReactDOM.flushSync`][flush-sync] call instead of the default [`React.startTransition`][start-transition]. This allows you to perform synchronous DOM actions immediately after the update is flushed to the DOM.

<docs-warning>`unstable_flushSync` only works when using a data router, see [Picking a Router][picking-a-router]</docs-warning>

<docs-warning>`ReactDOM.flushSync` de-optimizes React and can hurt the performance of your app.</docs-warning>

<docs-warning>Please note that this API is marked unstable and may be subject to breaking changes without a major release</docs-warning>

## `options.unstable_viewTransition`

The `unstable_viewTransition` option enables a [View Transition][view-transitions] for this navigation by wrapping the final state update in `document.startViewTransition()`. If you need to apply specific styles for this view transition, you will also need to leverage the [`unstable_useViewTransitionState()`][use-view-transition-state].
Expand All @@ -102,3 +114,5 @@ The `unstable_viewTransition` option enables a [View Transition][view-transition
[use-view-transition-state]: ../hooks//use-view-transition-state
[view-transitions]: https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
[picking-a-router]: ../routers/picking-a-router
[flush-sync]: https://react.dev/reference/react-dom/flushSync
[start-transition]: https://react.dev/reference/react/startTransition
10 changes: 10 additions & 0 deletions docs/hooks/use-submit.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,15 @@ Because submissions are navigations, the options may also contain the other navi
- `state`
- `unstable_viewTransition`

### `options.unstable_flushSync`

The `unstable_flushSync` option tells React Router DOM to wrap the initial state update for this submission in a [`ReactDOM.flushSync`][flush-sync] call instead of the default [`React.startTransition`][start-transition]. This allows you to perform synchronous DOM actions immediately after the update is flushed to the DOM.

<docs-warning>`ReactDOM.flushSync` de-optimizes React and can hurt the performance of your app.</docs-warning>

<docs-warning>Please note that this API is marked unstable and may be subject to breaking changes without a major release</docs-warning>

[pickingarouter]: ../routers/picking-a-router
[form]: ../components/form
[flush-sync]: https://react.dev/reference/react-dom/flushSync
[start-transition]: https://react.dev/reference/react/startTransition
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
},
"filesize": {
"packages/router/dist/router.umd.min.js": {
"none": "49.0 kB"
"none": "49.2 kB"
},
"packages/react-router/dist/react-router.production.min.js": {
"none": "13.9 kB"
Expand All @@ -119,10 +119,10 @@
"none": "16.3 kB"
},
"packages/react-router-dom/dist/react-router-dom.production.min.js": {
"none": "16.1 kB"
"none": "16.7 kB"
},
"packages/react-router-dom/dist/umd/react-router-dom.production.min.js": {
"none": "22.3 kB"
"none": "22.9 kB"
}
}
}
Loading

0 comments on commit 1193ae5

Please sign in to comment.