@modern-js/main-doc 2.36.0 → 2.37.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -265,7 +265,7 @@ export default function UserLayout() {
265
265
  <div>
266
266
  <span>{userInfo.name}</span>
267
267
  <span>{userInfo.age}</span>
268
- <Outlet>
268
+ <Outlet/>
269
269
  </div>
270
270
  )}>
271
271
  </Await>
@@ -281,6 +281,55 @@ For details on how to use the Await component, please refer to [Await](https://r
281
281
  For details on how to use defer, please refer to [defer](https://reactrouter.com/en/main/guides/deferred).
282
282
  :::
283
283
 
284
+ ### Data Cache
285
+
286
+ In routing navigation, Modern.js will only load the data of the changed part of the route.
287
+ For example, the current route is `a/b`, and the Data Loader corresponding to the `a` path has been executed.
288
+ When jumping from `/a/b` to `/a/c`, the Data Loader corresponding to `a` path will not be re-executed,
289
+ and the Data Loader corresponding to `c` path will execute and fetch the data.
290
+
291
+ It is mean that Modern.js will only load the data for the routing change portion of the data load,
292
+ and this default optimization strategy avoids invalid duplicate data requests.
293
+
294
+ You may ask, how to update the data of the `a` path corresponding to the Data Loader?
295
+
296
+ In Modern.js, Modern.js will reload the data of the corresponding routing path in the following cases:
297
+
298
+ 1. After [Data Action](/guides/basic-features/data/data-write.md) is triggered
299
+ 2. The search params on the url have changed.
300
+ 3. The link clicked by the user is the same as the URL of the current page.
301
+ 4. The [`shouldRevalidate`](#/shouldrevalidate) function is defined in the routing component, which returns true
302
+
303
+ :::info
304
+ If you define the [`shouldRevalidate`](#/shouldrevalidate) function on the route, the function will be checked first to determine whether the data needs to be reloaded.
305
+ :::
306
+
307
+ ### `shouldRevalidate`
308
+
309
+ In each routing component (`layout.tsx`, `page.tsx`, `$.tsx`), we can export a `shouldRevalidate` function, which is triggered each time a route changes in the project. This function controls which routes' data are reloaded, and when it returns true, the data for the corresponding route is reloaded. data of the corresponding route will be reloaded.
310
+
311
+ ```ts title="routes/user/layout.tsx"
312
+ import type { ShouldRevalidateFunction } from '@modern-js/runtime/router';
313
+ export const shouldRevalidate: ShouldRevalidateFunction = ({
314
+ actionResult,
315
+ currentParams,
316
+ currentUrl,
317
+ defaultShouldRevalidate,
318
+ formAction,
319
+ formData,
320
+ formEncType,
321
+ formMethod,
322
+ nextParams,
323
+ nextUrl,
324
+ }) => {
325
+ return true;
326
+ };
327
+ ```
328
+
329
+ :::info
330
+ For more details about the `shouldRevalidate` function, please refer to [react-router](https://reactrouter.com/en/main/route/should-revalidate)
331
+ :::
332
+
284
333
  ### Incorrect usage
285
334
 
286
335
  1. The `loader` can only return serializable data. In the SSR environment, the return value of the `loader` function will be serialized as a JSON string and then deserialized into an object on the client side. Therefore, the `loader` function cannot return non-serializable data (such as functions).
@@ -186,10 +186,6 @@ import { Helmet } from '@modern-js/runtime/head';
186
186
  import { useModel } from '@modern-js/runtime/model';
187
187
  import { List } from 'antd';
188
188
  import Item from '../components/Item';
189
- import { Helmet } from '@modern-js/runtime/head';
190
- import { useModel } from '@modern-js/runtime/model';
191
- import { List } from 'antd';
192
- import Item from '../components/Item';
193
189
  import contacts from '../models/contacts';
194
190
 
195
191
  function Contacts({
@@ -125,7 +125,7 @@ export default defineConfig({
125
125
  'landing-page': process.env.NODE_ENV !== 'production',
126
126
  },
127
127
  },
128
- };
128
+ });
129
129
  ```
130
130
 
131
131
  So far, the prototype of our point of contact list application is almost complete 👏👏👏.
@@ -219,6 +219,7 @@ export function UserLayout() {
219
219
 
220
220
  如果想获取 `entry1/routes/layout.tsx` 中 `loader` 返回的数据,`routeId` 的值就是 `entry1_layout`。
221
221
 
222
+
222
223
  ### (WIP)Loading UI
223
224
 
224
225
  :::info
@@ -277,7 +278,50 @@ defer 的具体用法请查看 [defer](https://reactrouter.com/en/main/guides/de
277
278
 
278
279
  :::
279
280
 
280
- {/* TODO 缓存相关 */}
281
+ ### 数据缓存
282
+
283
+ 在路由导航时,Modern.js 只会加载路由变化的部分的数据,如当前路由是 `a/b`,`a` 路径对应的 Data Loader 已经执行过,当从 `/a/b` 跳转到 `/a/c`时,`a` 路径对应的 Data Loader 不会重新执行,`c` 路径对应的 Data Loader 会执行,并获取了数据。
284
+
285
+ 即 Modern.js 在数据加载时,只会加载路由变化部分的数据,这种默认的优化策略避免了无效重复数据的请求。
286
+
287
+ 你可能会问,如何更新 `a` 路径对应 Data Loader 的数据?
288
+
289
+ 在 Modern.js 中,以下几种情况,Modern.js 会重新加载对应路由路径的数据:
290
+
291
+ 1. 在 [Data Action](/guides/basic-features/data/data-write.md) 触发后
292
+ 2. URL 上搜索参数发生了变化
293
+ 3. 用户点击的链接与当前页面的 URL 相同
294
+ 4. 在路由组件中定义了 [`shouldRevalidate`](#/shouldrevalidate) 函数,该函数返回 true
295
+
296
+ :::info
297
+ 如果你在路由上定义了 [`shouldRevalidate`](#/shouldrevalidate) 函数,会先检查该函数,判断是否需要重新加载数据。
298
+ :::
299
+
300
+ ### `shouldRevalidate`
301
+
302
+ 在每个路由组件(`layout.tsx`,`page.tsx`, `$.tsx`)中,我们可以导出一个 `shouldRevalidate` 函数,在每次项目中的路由变化时,这个函数会触发,该函数可以控制要重新加载哪些路由中的数据,当这个函数返回 true, 对应路由的数据就会重新加载。
303
+
304
+ ```ts title="routes/user/layout.tsx"
305
+ import type { ShouldRevalidateFunction } from '@modern-js/runtime/router';
306
+ export const shouldRevalidate: ShouldRevalidateFunction = ({
307
+ actionResult,
308
+ currentParams,
309
+ currentUrl,
310
+ defaultShouldRevalidate,
311
+ formAction,
312
+ formData,
313
+ formEncType,
314
+ formMethod,
315
+ nextParams,
316
+ nextUrl,
317
+ }) => {
318
+ return true;
319
+ };
320
+ ```
321
+
322
+ :::info
323
+ `shouldRevalidate` 函数的更多信息可以参考 [react-router](https://reactrouter.com/en/main/route/should-revalidate)
324
+ :::
281
325
 
282
326
  ### 错误用法
283
327
 
@@ -186,10 +186,6 @@ import { Helmet } from '@modern-js/runtime/head';
186
186
  import { useModel } from '@modern-js/runtime/model';
187
187
  import { List } from 'antd';
188
188
  import Item from '../components/Item';
189
- import { Helmet } from '@modern-js/runtime/head';
190
- import { useModel } from '@modern-js/runtime/model';
191
- import { List } from 'antd';
192
- import Item from '../components/Item';
193
189
  import contacts from '../models/contacts';
194
190
 
195
191
  function Contacts({
@@ -125,7 +125,7 @@ export default defineConfig({
125
125
  'landing-page': process.env.NODE_ENV !== 'production',
126
126
  },
127
127
  },
128
- };
128
+ });
129
129
  ```
130
130
 
131
131
  到底为止,我们的联系人列表应用的雏形就基本完成了 👏👏👏。
package/package.json CHANGED
@@ -15,17 +15,17 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.36.0",
18
+ "version": "2.37.0",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public",
22
22
  "provenance": true
23
23
  },
24
24
  "dependencies": {
25
- "@modern-js/sandpack-react": "2.36.0"
25
+ "@modern-js/sandpack-react": "2.37.0"
26
26
  },
27
27
  "peerDependencies": {
28
- "@modern-js/builder-doc": "^2.36.0"
28
+ "@modern-js/builder-doc": "^2.37.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "classnames": "^2",
@@ -35,12 +35,12 @@
35
35
  "ts-node": "^10.9.1",
36
36
  "typescript": "^5",
37
37
  "fs-extra": "^10",
38
- "rspress": "1.0.0-beta.3",
39
- "@rspress/shared": "1.0.0-beta.3",
38
+ "rspress": "1.0.2",
39
+ "@rspress/shared": "1.0.2",
40
40
  "@types/node": "^16",
41
41
  "@types/fs-extra": "^9",
42
- "@modern-js/builder-doc": "2.36.0",
43
- "@modern-js/doc-plugin-auto-sidebar": "2.36.0"
42
+ "@modern-js/builder-doc": "2.37.0",
43
+ "@modern-js/doc-plugin-auto-sidebar": "2.37.0"
44
44
  },
45
45
  "scripts": {
46
46
  "dev": "rspress dev",