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
Copy file name to clipboardExpand all lines: docs/explanation/code-splitting.md
+43-3Lines changed: 43 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,46 @@ title: Automatic Code Splitting
4
4
5
5
# Automatic Code Splitting
6
6
7
-
<docs-warning>
8
-
This document is a work in progress. There's not much to see here (yet).
9
-
</docs-warning>
7
+
When using React Router's framework features, your application is automatically code split to improve the performance of initial load times when users visit your application.
8
+
9
+
## Code Splitting by Route
10
+
11
+
Consider this simple route config:
12
+
13
+
```tsx filename=routes.ts
14
+
exportdefault [
15
+
route("/contact", "./contact.tsx"),
16
+
route("/about", "./about.tsx"),
17
+
];
18
+
```
19
+
20
+
Instead of bundling all routes into a single giant build, the modules referenced (`contact.tsx` and `about.tsx`) become entry points to the bundler.
21
+
22
+
Because these entry points are coupled to URL segments, React Router knows just from a URL which bundles are needed in the browser, and more importantly, which are not.
23
+
24
+
If the user visits `"/about"` then the bundles for `about.tsx` will be loaded but not `contact.tsx`. This ensures drastically reduces the JavaScript footprint for initial page loads and speeds up your application.
25
+
26
+
## Removal of Server Code
27
+
28
+
Any server-only Route Module APIs will be removed from the bundles. Consider this route module:
29
+
30
+
```tsx
31
+
exportasyncfunction loader() {
32
+
return { message: "hello" };
33
+
}
34
+
35
+
exportasyncfunction action() {
36
+
console.log(Date.now());
37
+
return { ok: true };
38
+
}
39
+
40
+
exportasyncfunction headers() {
41
+
return { "Cache-Control": "max-age=300" };
42
+
}
43
+
44
+
exportdefaultfunction Component({ loaderData }) {
45
+
return <div>{loaderData.message}</div>;
46
+
}
47
+
```
48
+
49
+
After building for the browser, only the `Component` will still be in the bundle, so you can use server-only code in the other module exports.
Copy file name to clipboardExpand all lines: docs/explanation/race-conditions.md
+77-3Lines changed: 77 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,80 @@ title: Race Conditions
4
4
5
5
# Race Conditions
6
6
7
-
<docs-warning>
8
-
This document is a work in progress. There's not much to see here (yet).
9
-
</docs-warning>
7
+
While impossible to eliminate every possible race condition in your application, React Router automatically handles the most common race conditions found in web user interfaces.
8
+
9
+
## Browser Behavior
10
+
11
+
React Router's handling of network concurrency is heavily inspired by the behavior of web browsers when processing documents.
12
+
13
+
Consider clicking a link to a new document, and then clicking a different link before the new page has finished loading. The browser will:
14
+
15
+
1. cancel the first request
16
+
2. immediately processes the new navigation
17
+
18
+
This behavior includes form submissions. When a pending form submission is interrupted by a new one, the first is canceled and the new submission is immediately processed.
19
+
20
+
## React Router Behavior
21
+
22
+
Like the browser, interrupted navigations with links and form submissions will cancel in flight data requests and immediately process the new event.
23
+
24
+
Fetchers are a bit more nuanced since they are not singleton events like navigation. Fetchers can't interrupt a other fetcher instances, but they can interrupt themselves and the behavior is the same as everything else: cancel the interrupted request and immediately process the new one.
25
+
26
+
Fetchers do, however, interact with each when it comes to revalidation. After a fetcher's action request returns to the browser, a revalidation for all page data is sent. This means multiple revalidation requests can be in-flight at the same time. React Router will commit all "fresh" revalidation responses and cancel any stale requests. A stale request is any request that started _earlier_ than one that has returned.
27
+
28
+
This management of the network prevents the most common UI bugs caused by network race conditions.
29
+
30
+
Since networks are unpredictable, and your server still processes these cancelled requests, your backend may still experience race conditions and have potential data integrity issues. These risks are the same risks as using default browser behavior with plain HTML `<forms>`, which we consider to be low, and outside the scope of React Router.
31
+
32
+
## Practical Benefits
33
+
34
+
Consider building a type-ahead combobox. As the user types, you send a request to the server. As they type each new character you send a new request. It's important to not show the user results for a value that's not in the text field anymore.
35
+
36
+
When using a fetcher, this is automatically managed for you. Consider this pseudo-code:
37
+
38
+
```tsx
39
+
// route("/city-search", "./search-cities.ts")
40
+
exportasyncfunction loader({ request }) {
41
+
const { searchParams } =newURL(request.url);
42
+
returnsearchCities(searchParams.get("q"));
43
+
}
44
+
```
45
+
46
+
```tsx
47
+
exportfunction CitySearchCombobox() {
48
+
const fetcher =useFetcher();
49
+
50
+
return (
51
+
<fetcher.Formaction="/city-search">
52
+
<Comboboxaria-label="Cities">
53
+
<ComboboxInput
54
+
name="q"
55
+
onChange={(event) =>
56
+
// submit the form onChange to get the list of cities
57
+
fetcher.submit(event.target.form)
58
+
}
59
+
/>
60
+
61
+
{fetcher.data? (
62
+
<ComboboxPopoverclassName="shadow-popup">
63
+
{fetcher.data.length>0? (
64
+
<ComboboxList>
65
+
{fetcher.data.map((city) => (
66
+
<ComboboxOption
67
+
key={city.id}
68
+
value={city.name}
69
+
/>
70
+
))}
71
+
</ComboboxList>
72
+
) : (
73
+
<span>No results found</span>
74
+
)}
75
+
</ComboboxPopover>
76
+
) :null}
77
+
</Combobox>
78
+
</fetcher.Form>
79
+
);
80
+
}
81
+
```
82
+
83
+
Calls to `fetcher.submit` will cancel pending requests on that fetcher automatically. This ensures you never show the user results for a request for a different input value.
Copy file name to clipboardExpand all lines: docs/explanation/type-safety.md
+2-4Lines changed: 2 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,10 @@
1
1
---
2
-
title: Type safety
2
+
title: Type Safety
3
3
---
4
4
5
-
# Type safety
5
+
# Type Safety
6
6
7
-
<docs-info>
8
7
If you haven't done so already, check out our guide for <ahref="../framework/how-to/setting-up-type-safety">setting up type safety</a> in a new project.
9
-
</docs-info>
10
8
11
9
React Router generates types for each route in your app that you can use to get type safety for each route module export.
0 commit comments