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
This release stabilizes the `future.unstable_skipActionErrorRevalidation` flag into [`future.v7_skipActionErrorRevalidation`](https://reactrouter.com/upgrading/future#v7_skipactionstatusrevalidation) in preparation for the upcoming React Router v7 release.
210
+
211
+
- When this flag is enabled, actions that return/throw a `4xx/5xx``Response` will not trigger a revalidation by default
212
+
- This also stabilizes `shouldRevalidate`'s `unstable_actionStatus` parameter to `actionStatus`
213
+
214
+
### Minor Changes
215
+
216
+
- Stabilize `future.unstable_skipActionErrorRevalidation` as `future.v7_skipActionErrorRevalidation` ([#11769](https://github.com/remix-run/react-router/pull/11769))
217
+
218
+
### Patch Changes
219
+
220
+
- Fix regression and properly decode paths inside `useMatch` so matches/params reflect decoded params ([#11789](https://github.com/remix-run/react-router/pull/11789))
221
+
- Fix bubbling of errors thrown from `unstable_patchRoutesOnMiss` ([#11786](https://github.com/remix-run/react-router/pull/11786))
222
+
- Fix hydration in SSR apps using `unstable_patchRoutesOnMiss` that matched a splat route on the server ([#11790](https://github.com/remix-run/react-router/pull/11790))
@@ -40,8 +40,8 @@ There are several instances where data is revalidated, keeping your UI in sync w
40
40
41
41
- After an [`action`][action] is called via:
42
42
-[`<Form>`][form], [`<fetcher.Form>`][fetcher], [`useSubmit`][usesubmit], or [`fetcher.submit`][fetcher]
43
-
- When the `future.unstable_skipActionErrorRevalidation` flag is enabled, `loaders` will not revalidate by default if the `action` returns or throws a 4xx/5xx `Response`
44
-
- You can opt-into revalidation for these scenarios via `shouldRevalidate` and the `unstable_actionStatus` parameter
43
+
- When the `future.v7_skipActionErrorRevalidation` flag is enabled, `loaders` will not revalidate by default if the `action` returns or throws a 4xx/5xx `Response`
44
+
- You can opt-into revalidation for these scenarios via `shouldRevalidate` and the `actionStatus` parameter
45
45
- When an explicit revalidation is triggered via [`useRevalidator`][userevalidator]
46
46
- When the [URL params][params] change for an already rendered route
Copy file name to clipboardExpand all lines: docs/routers/create-browser-router.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -125,7 +125,7 @@ The following future flags are currently available:
125
125
|`v7_partialHydration`| Support partial hydration for Server-rendered apps |
126
126
|`v7_prependBasename`| Prepend the router basename to navigate/fetch paths |
127
127
|[`v7_relativeSplatPath`][relativesplatpath]| Fix buggy relative path resolution in splat routes |
128
-
|`unstable_skipActionErrorRevalidation`| Do not revalidate by default if the action returns a 4xx/5xx `Response`|
128
+
|`v7_skipActionErrorRevalidation`| Do not revalidate by default if the action returns a 4xx/5xx `Response`|
129
129
130
130
## `opts.hydrationData`
131
131
@@ -246,7 +246,7 @@ interface HandlerResult {
246
246
- If you are on `/parent/child/a` and you submit to `a`'s `action`, then only `a` will have `shouldLoad=true` for the action execution of `dataStrategy`
247
247
- After the `action`, `dataStrategy` will be called again for the `loader` revalidation, and all matches will have `shouldLoad=true` (assuming no custom `shouldRevalidate` implementations)
248
248
249
-
The `dataStrategy` function should return a parallel array of `HandlerResult` instances, which indicates if the handler was successful or not. If the returned `handlerResult.result` is a `Response`, React Router will unwrap it for you (via `res.json` or `res.text`). If you need to do custom decoding of a `Response` but preserve the status code, you can return the decoded value in `handlerResult.result` and send the status along via `handlerResult.status` (for example, when using the `future.unstable_skipActionRevalidation` flag). `match.resolve()` will return a `HandlerResult` if you are not passing it a handler override function. If you are, then you need to wrap the `handler` result in a `HandlerResult` (see examples below).
249
+
The `dataStrategy` function should return a parallel array of `HandlerResult` instances, which indicates if the handler was successful or not. If the returned `handlerResult.result` is a `Response`, React Router will unwrap it for you (via `res.json` or `res.text`). If you need to do custom decoding of a `Response` but preserve the status code, you can return the decoded value in `handlerResult.result` and send the status along via `handlerResult.status` (for example, when using the `future.v7_skipActionRevalidation` flag). `match.resolve()` will return a `HandlerResult` if you are not passing it a handler override function. If you are, then you need to wrap the `handler` result in a `HandlerResult` (see examples below).
<docs-warning>If you are not using a `createBrowserRouter` you can skip this</docs-warning>
206
+
207
+
When this flag is enabled, loaders will no longer revalidate by default after an action throws/returns a `Response` with a `4xx`/`5xx` status code. You may opt-into revalidation in these scenarios via `shouldRevalidate` and the `actionStatus` parameter.
208
+
209
+
👉 **Enable the Flag**
210
+
211
+
```tsx
212
+
createBrowserRouter(routes, {
213
+
future: {
214
+
v7_skipActionStatusRevalidation: true,
215
+
},
216
+
});
217
+
```
218
+
219
+
**Update your Code**
220
+
221
+
In most cases, you probably won't have to make changes to your app code. Usually, if an action errors, it's unlikely data was mutated and needs revalidation. If any of your code _does_ mutate data in action error scenarios you have 2 options:
222
+
223
+
👉 **Option 1: Change the `action` to avoid mutations in error scenarios**
224
+
225
+
```js
226
+
// Before
227
+
asyncfunctionaction() {
228
+
awaitmutateSomeData();
229
+
if (detectError()) {
230
+
thrownewResponse(error, { status:400 });
231
+
}
232
+
awaitmutateOtherData();
233
+
// ...
234
+
}
235
+
236
+
// After
237
+
asyncfunctionaction() {
238
+
if (detectError()) {
239
+
thrownewResponse(error, { status:400 });
240
+
}
241
+
// All data is now mutated after validations
242
+
awaitmutateSomeData();
243
+
awaitmutateOtherData();
244
+
// ...
245
+
}
246
+
```
247
+
248
+
👉 **Option 2: Opt-into revalidation via `shouldRevalidate` and `actionStatus`**
0 commit comments