@@ -38,7 +38,7 @@ title: <Activity>
3838
3939通过这种方式,` Activity ` 可以被视为一种渲染“后台活动”的机制。与其完全丢弃那些可能再次显示的内容,不如使用 ` Activity ` 来保持并恢复这些内容的 UI 和内部状态,同时确保隐藏的内容不会产生多余的副作用。
4040
41- [ 请参阅下方的更多示例。 ] ( #usage )
41+ [ 请参阅下方的更多示例] 。 (#usage)
4242
4343#### Props {/* props* /}
4444
@@ -76,9 +76,9 @@ title: <Activity>
7676
7777这使得隐藏组件并随后将其恢复到之前的状态成为可能。
7878
79- 下方的示例包含一个带有可展开部分的侧边栏。你可以点击“ Overview” 来展开下方的三个子项。应用主区域还有一个可以隐藏或显示侧边栏的按钮。
79+ 下方的示例包含一个带有可展开部分的侧边栏。你可以点击 Overview 来展开下方的三个子项。应用主区域还有一个可以隐藏或显示侧边栏的按钮。
8080
81- 试着展开“ Overview” 部分,然后将侧边栏切换为关闭,再重新打开:
81+ 试着展开 Overview 部分,然后将侧边栏切换为关闭,再重新打开:
8282
8383<Sandpack >
8484
167167
168168</Sandpack >
169169
170- Overview部分最初总是处于折叠状态 。因为当 ` isShowingSidebar ` 切换为 ` false ` 时,我们会卸载侧边栏,这导致其所有的内部状态都丢失了
170+ Overview 部分最初总是处于折叠状态 。因为当 ` isShowingSidebar ` 切换为 ` false ` 时,我们会卸载侧边栏,这导致其所有的内部状态都丢失了
171171
172172这是 ` Activity ` 的一个完美用例。即使在视觉上隐藏侧边栏时,我们也可以保留其内部状态。
173173
283283
284284由于 ` Activity ` 边界使用 ` display: none ` 来隐藏其子组件,因此这些子组件的 DOM 在隐藏时也会被保留。这使得它们非常适合用于维护 UI 中那些用户可能会再次交互的部分的瞬时状态。
285285
286- 在此示例中,` Contact ` 组件包含一个 ` <textarea> ` ,用户可以在其中输入消息。如果你输入了一些文本,切换到` Home ` 组件 ,然后再切回` Contact ` 组件 ,那么草稿消息将会丢失:
286+ 在此示例中,` Contact ` 标签页包含一个 ` <textarea> ` ,用户可以在其中输入消息。如果你输入了一些文本,切换到 ` Home ` 标签页 ,然后再切回 ` Contact ` 标签页 ,那么草稿消息将会丢失:
287287
288288<Sandpack >
289289
@@ -369,9 +369,9 @@ b { display: inline-block; margin-right: 10px; }
369369
370370</Sandpack >
371371
372- 这是因为我们在 ` App ` 组件中完全卸载了 ` Contact ` 组件 。当` Contact ` 组件被卸载时 ,` <textarea> ` 元素的内部 DOM 状态也就丢失了。
372+ 这是因为我们在 ` App ` 组件中完全卸载了 ` Contact ` 。当` Contact ` 组标签页被卸载时 ,` <textarea> ` 元素的内部 DOM 状态也就丢失了。
373373
374- 如果我们改用 ` Activity ` 边界来显示和隐藏当前活跃的组件,我们就能保留每个组件的 DOM 状态。试着再次输入文本并切换组件 ,你会发现草稿消息不再被重置:
374+ 如果我们改用 ` Activity ` 边界来显示和隐藏当前活跃的标签页,我们就能保留每个标签页的 DOM 状态。试着再次输入文本并切换标签页 ,你会发现草稿消息不再被重置:
375375
376376<Sandpack >
377377
@@ -461,29 +461,29 @@ b { display: inline-block; margin-right: 10px; }
461461
462462</Sandpack >
463463
464- 同样地,` Activity ` 边界让我们能够在不改变` Contact ` 组件实现逻辑的情况下 ,保留其内部状态。
464+ 同样地,` Activity ` 边界让我们能够在不改变 ` Contact ` 标签页实现逻辑的情况下 ,保留其内部状态。
465465
466466---
467467
468468### 预渲染可能变为可见的内容 {/* pre-rendering-content-thats-likely-to-become-visible* /}
469469
470470到目前为止,我们已经了解了 ` Activity ` 是如何在隐藏用户交互过的内容的同时,而不丢弃这些内容的瞬时状态(ephemeral state)的。
471471
472- 不仅如此,` Activity ` 边界还可以用来预先准备那些用户尚未初次看到的内容 :
472+ 不仅如此,` Activity ` 边界还可以用来预先 ** 准备 ** 那些用户尚未初次看到的内容 :
473473
474474``` jsx [[1, 1, "\\ "hidden\\ ""]]
475475< Activity mode= " hidden" >
476476 < SlowComponent / >
477477< / Activity>
478478```
479479
480- 当 ` Activity ` 边界在初次渲染时处于 <CodeStep step ={1} >隐藏</CodeStep > 状态,其子组件虽然不会在页面上显示,但它们仍会被渲染 。不过,它们的渲染优先级会低于可见内容,且不会挂载它们的 Effect。
480+ 当 ` Activity ` 边界在初次渲染时处于 <CodeStep step ={1} >隐藏</CodeStep > 状态,其子组件虽然不会在页面上显示,但它们 ** 仍会被渲染 ** 。不过,它们的渲染优先级会低于可见内容,且不会挂载它们的 Effect。
481481
482- 这种“预渲染”允许子组件提前加载所需的任何代码或数据。这样一来,当随后 ` Activity ` 边界变为可见时,子组件就能以更短的加载时间实现更快的呈现。
482+ 这种“** 预渲染** ”允许子组件提前加载所需的任何代码或数据。这样一来,当随后 ` Activity ` 边界变为可见时,子组件就能以更短的加载时间实现更快的呈现。
483483
484484让我们来看一个示例。
485485
486- 在此演示中,` Posts ` 组件会加载一些数据 。如果你点击它,在获取数据的过程中,你会看到显示出的 ` Suspense ` 回退内容:
486+ 在此演示中,` Posts ` 标签页会加载一些数据 。如果你点击它,在获取数据的过程中,你会看到显示出的 ` Suspense ` 回退内容:
487487
488488<Sandpack >
489489
@@ -611,11 +611,11 @@ video { width: 300px; margin-top: 10px; aspect-ratio: 16/9; }
611611
612612</Sandpack >
613613
614- 这是因为 ` App ` 组件直到` Posts ` 组件变为活跃状态时才会挂载 ` Posts ` 组件
614+ 这是因为 ` App ` 组件直到 ` Posts ` 标签页变为活跃状态时才会挂载 ` Posts `
615615
616- 如果我们更新 ` App ` ,改用 ` Activity ` 边界来显示和隐藏活跃组件 ,那么 ` Posts ` 组件将在应用初始加载时被预渲染 ,从而允许它在变得可见之前就获取到所需数据。
616+ 如果我们更新 ` App ` ,改用 ` Activity ` 边界来显示和隐藏活跃标签页 ,那么 ` Posts ` 将在应用初始加载时被预渲染 ,从而允许它在变得可见之前就获取到所需数据。
617617
618- 现在试着点击` Posts ` 组件 :
618+ 现在试着点击 ` Posts ` 标签页 :
619619
620620<Sandpack >
621621
@@ -774,7 +774,7 @@ video { width: 300px; margin-top: 10px; aspect-ratio: 16/9; }
774774
775775### 加快页面加载过程中的交互速度 {/* speeding-up-interactions-during-page-load* /}
776776
777- React 包含一项名为“选择性注水”的底层性能优化。它的工作原理是 _ 分块 _ 注水应用的初始 HTML,从而使部分组件即使在页面上其他组件的代码或数据尚未加载完成时,也能先变得可交互。
777+ React 包含一项名为“选择性注水”的底层性能优化。它的工作原理是 ** 分块 ** 注水应用的初始 HTML,从而使部分组件即使在页面上其他组件的代码或数据尚未加载完成时,也能先变得可交互。
778778
779779` Suspense ` 边界参与了“选择性注水”,因为它们很自然地将你的组件树划分成了彼此独立的单元:
780780
@@ -798,7 +798,7 @@ function Page() {
798798
799799但是,对于那些没有使用 ` Suspense ` 的页面又该怎么办呢?
800800
801- 以这个组件示例为例 :
801+ 以这个标签页示例为例 :
802802
803803``` jsx
804804function Page () {
@@ -824,9 +824,9 @@ function Page() {
824824}
825825```
826826
827- 在这种情况下,React 必须一次性对整个页面进行注水。如果 ` Home ` 或 ` Video ` 组件的渲染速度较慢 ,它们可能会导致标签页按钮在注水期间感觉响应迟钝。
827+ 在这种情况下,React 必须一次性对整个页面进行注水。如果 ` Home ` 或 ` Video ` 的渲染速度较慢 ,它们可能会导致标签页按钮在注水期间感觉响应迟钝。
828828
829- 在活跃的组件周围添加 ` Suspense ` 可以解决这个问题:
829+ 在活跃的标签页周围添加 ` Suspense ` 可以解决这个问题:
830830
831831``` jsx {13,20}
832832function Page () {
@@ -858,7 +858,7 @@ function Page() {
858858
859859相反,我们可以使用 ` Activity ` 。由于 ` Activity ` 边界负责显示和隐藏其子组件,它们已经自然地将组件树划分成了彼此独立的单元。而且与 ` Suspense ` 一样,这一特性使得它们能够参与到“选择性注水(Selective Hydration)”中。
860860
861- 让我们更新示例,在活跃的组件周围使用 ` Activity ` 边界:
861+ 让我们更新示例,在活跃的标签页周围使用 ` Activity ` 边界:
862862
863863``` jsx {13-18}
864864function Page () {
@@ -884,7 +884,7 @@ function Page() {
884884}
885885```
886886
887- 现在,我们初始的服务端渲染HTML 看起来与原始版本完全一致;但多亏了 ` Activity ` ,React 可以优先对组件按钮进行注水 ,甚至在挂载 ` Home ` 或 ` Video ` 组件之前就完成这一操作。
887+ 现在,我们初始的服务端渲染HTML 看起来与原始版本完全一致;但多亏了 ` Activity ` ,React 可以优先对标签页按钮进行注水 ,甚至在挂载 ` Home ` 或 ` Video ` 组件之前就完成这一操作。
888888
889889---
890890
@@ -914,7 +914,7 @@ function Page() {
914914
915915` Activity ` 边界通过在其子组件上设置 ` display: none ` 并清理它们所有的 Effect 来隐藏内容。因此,大多数遵循最佳实践、能够正确清理自身副作用的 React 组件,在被 ` Activity ` 隐藏时都具有足够的健壮性。
916916
917- 但是,在某些情况下 ,隐藏组件的表现与卸载组件确实有所不同。最显著的一点是:由于隐藏组件的 DOM 并没有被销毁,来自该 DOM 的任何副作用都将持续存在,即便在组件被隐藏之后也是如此。
917+ 但是,也 ** 确实存在 ** 一些情况下 ,隐藏组件的表现与卸载组件确实有所不同。最显著的一点是:由于隐藏组件的 DOM 并没有被销毁,来自该 DOM 的任何副作用都将持续存在,即便在组件被隐藏之后也是如此。
918918
919919以 ` <video> ` 标签为例。通常它不需要任何显式的清理逻辑,因为即使你正在播放视频,卸载该标签也会让浏览器自动停止视频和音频的播放。在下面这个演示中,请试着播放视频,然后点击 ` Home ` 组件:
920920
@@ -1001,11 +1001,11 @@ video { width: 300px; margin-top: 10px; aspect-ratio: 16/9; }
10011001
10021002视频如预期般停止播放。
10031003
1004- 现在,假设我们想要保留用户最后观看的时间点,以便当他们切回 ` Video ` 组件时 ,视频不会从头开始播放。
1004+ 现在,假设我们想要保留用户最后观看的时间点,以便当他们切回 ` Video ` 标签页时 ,视频不会从头开始播放。
10051005
10061006这正是 ` Activity ` 的绝佳用例!
10071007
1008- 让我们更新 ` App ` 组件,使用隐藏的 ` Activity ` 边界来隐藏非活跃组件 ,而不是将其卸载,看看这次演示的表现如何:
1008+ 让我们更新 ` App ` 组件,使用隐藏的 ` Activity ` 边界来隐藏非活跃标签页 ,而不是将其卸载,看看这次演示的表现如何:
10091009
10101010<Sandpack >
10111011
@@ -1092,7 +1092,7 @@ video { width: 300px; margin-top: 10px; aspect-ratio: 16/9; }
10921092
10931093</Sandpack >
10941094
1095- 糟糕!即便在被隐藏之后,视频和音频仍在继续播放,因为该组件的 ` <video> ` 元素依然存在于 DOM 中。
1095+ 糟糕!即便在被隐藏之后,视频和音频仍在继续播放,因为该标签页的 ` <video> ` 元素依然存在于 DOM 中。
10961096
10971097为了修复这个问题,我们可以添加一个带有清理函数的 Effect,用于暂停视频播放:
10981098
@@ -1122,7 +1122,7 @@ export default function VideoTab() {
11221122
11231123我们调用 ` useLayoutEffect ` 而不是 ` useEffect ` ,是因为从概念上讲,清理代码是与组件 UI 的“视觉隐藏”紧密绑定的。如果我们使用普通的 Effect,代码逻辑可能会因为(例如)某个正在重新挂起的 ` Suspense ` 边界或视图过渡而发生延迟。
11241124
1125- 让我们看看新的表现。试着播放视频,切换到` Home ` 组件 ,然后再切换回` Video ` 组件 :
1125+ 让我们看看新的表现。试着播放视频,切换到 ` Home ` 标签页 ,然后再切换回 ` Video ` 标签页 :
11261126
11271127<Sandpack >
11281128
0 commit comments