@@ -4,7 +4,7 @@ title: createPortal
4
4
5
5
<Intro >
6
6
7
- ` createPortal ` 允许你将一些子元素渲染到 DOM 的不同部分。
7
+ ` createPortal ` 允许你将 JSX 作为 children 渲染至 DOM 的不同部分。
8
8
9
9
10
10
``` js
@@ -32,33 +32,33 @@ import { createPortal } from 'react-dom';
32
32
// ...
33
33
34
34
< div>
35
- < p> This child is placed in the parent div. < / p>
35
+ < p> 这个子节点被放置在父节点 div 中。 < / p>
36
36
{createPortal (
37
- < p> This child is placed in the document body. < / p> ,
37
+ < p> 这个子节点被放置在 document body 中。 < / p> ,
38
38
document .body
39
39
)}
40
40
< / div>
41
41
` ` `
42
42
43
- [请查看以下更多示例 ](#usage)。
43
+ [参见下方更多示例 ](#usage)。
44
44
45
- portal 只改变 DOM 节点的所处位置。在其他方面,传入 portal 中的 JSX 将作为渲染它的 React 组件的子节点 。该子节点可以访问由父节点树提供的 context 对象、事件将从子节点冒泡到父节点树,以及遵循 React 树的规则 。
45
+ portal 只改变 DOM 节点的所处位置。在其他方面,渲染至 portal 的 JSX 的行为表现与作为 React 组件的子节点一致 。该子节点可以访问由父节点树提供的 context 对象、事件将从子节点依循 React 树冒泡到父节点 。
46
46
47
47
#### 参数 {/*parameters*/}
48
48
49
- * ` children` :React 可以渲染的任何内容,例如 JSX 片段(` < div / > ` 或 ` < SomeComponent / > ` 等等)、[Fragment](/reference/react/Fragment)(` <> ... < / > ` )、字符串或数字,以及这些内容构成的数组。
49
+ * ` children` :React 可以渲染的任何内容,如 JSX 片段(` < div / > ` 或 ` < SomeComponent / > ` 等等)、[Fragment](/reference/react/Fragment)(` <> ... < / > ` )、字符串或数字,以及这些内容构成的数组。
50
50
51
- * ` domNode` :某个 DOM 节点,例如由 ` document .getElementById ()` 返回的节点。节点必须已经存在。 在更新过程中传递不同的 DOM 节点将导致 portal 内容被重新创建 。
51
+ * ` domNode` :某个已经存在的 DOM 节点,例如由 ` document .getElementById ()` 返回的节点。在更新过程中传递不同的 DOM 节点将导致 portal 内容被重建 。
52
52
53
- #### 返回值 {/*returns*/}
53
+ * **可选参数** ` key ` :用作 portal [key](/learn/rendering-lists/#keeping-list-items-in-order-with-key) 的独特字符串或数字。
54
54
55
- * **可选的** ` key ` : 用作 portal [key](/learn/rendering-lists/#keeping-list-items-in-order-with-key) 的独特字符串或数字。
55
+ #### 返回值 {/*returns*/}
56
56
57
- ` createPortal` 返回一个 React 节点,该节点可以包含在 JSX 中或从 React 组件中返回 。如果 React 在渲染输出中遇见它,它将把提供的 ` children` 放入提供的 ` domNode` 中。
57
+ ` createPortal` 返回一个可以包含在 JSX 中或从 React 组件中返回的 React 节点 。如果 React 在渲染输出中遇见它,它将把提供的 ` children` 放入提供的 ` domNode` 中。
58
58
59
59
#### 警告 {/*caveats*/}
60
60
61
- * portal 中的事件传播遵循 React 树而不是 DOM 树。例如点击 ` < div onClick> ` 内部的 portal,将触发 ` onClick` 处理程序。如果这导致问题 ,请在 portal 内部停止事件传播,或将 portal 本身移动到 React 树中的上层。
61
+ * portal 中的事件传播遵循 React 树而不是 DOM 树。例如点击 ` < div onClick> ` 内部的 portal,将触发 ` onClick` 处理程序。如果这会导致意外的问题 ,请在 portal 内部停止事件传播,或将 portal 移动到 React 树中的上层。
62
62
63
63
---
64
64
@@ -68,27 +68,27 @@ portal 只改变 DOM 节点的所处位置。在其他方面,传入 portal 中
68
68
69
69
*portal* 允许组件将它们的某些子元素渲染到 DOM 中的不同位置。这使得组件的一部分可以“逃脱”它所在的容器。例如组件可以在页面其余部分上方或外部显示模态对话框和提示框。
70
70
71
- 要创建 portal,请使用 <CodeStep step={1}>JSX</CodeStep> 和 <CodeStep step={2}> 应该放置的 DOM 节点</CodeStep> 渲染 ` createPortal ` 的结果 :
71
+ 调用 ` createPortal ` 并传入 <CodeStep step={1}>JSX</CodeStep> 与 <CodeStep step={2}> 应该放置的 DOM 节点</CodeStep> 作为参数,然后渲染返回值以创建 portal :
72
72
73
73
` ` ` js [[1 , 8 , " <p>This child is placed in the document body.</p>" ], [2 , 9 , " document.body" ]]
74
74
import { createPortal } from ' react-dom' ;
75
75
76
76
function MyComponent () {
77
77
return (
78
78
< div style= {{ border: ' 2px solid black' }}>
79
- < p> This child is placed in the parent div. < / p>
79
+ < p> 这个子节点被放置在父节点 div 中。 < / p>
80
80
{createPortal (
81
- < p> This child is placed in the document body. < / p> ,
81
+ < p> 这个子节点被放置在 document body 中。 < / p> ,
82
82
document .body
83
83
)}
84
84
< / div>
85
85
);
86
86
}
87
87
` ` `
88
88
89
- React 将 <CodeStep step={1}>传递的 JSX</CodeStep> 的 DOM 节点放入 <CodeStep step={2}>提供的 DOM 节点</CodeStep> 中。
89
+ React 将 <CodeStep step={1}>传递的 JSX</CodeStep> 对应的 DOM 节点放入 <CodeStep step={2}>提供的 DOM 节点</CodeStep> 中。
90
90
91
- 如果没有 portal,第二个 ` < p> ` 将放置在父级 ` < div> ` 中,但 portal 将其 “传送”到 [` document .body ` ](https://developer.mozilla.org/zh-CN/docs/Web/API/Document/body) 中:
91
+ 如果没有 portal,第二个 ` < p> ` 将放置在父级 ` < div> ` 中,但 portal 会将其 “传送”到 [` document .body ` ](https://developer.mozilla.org/zh-CN/docs/Web/API/Document/body) 中:
92
92
93
93
<Sandpack>
94
94
@@ -98,9 +98,9 @@ import { createPortal } from 'react-dom';
98
98
export default function MyComponent () {
99
99
return (
100
100
< div style= {{ border: ' 2px solid black' }}>
101
- < p> This child is placed in the parent div. < / p>
101
+ < p> 这个子节点被放置在父节点 div 中。 < / p>
102
102
{createPortal (
103
- < p> This child is placed in the document body. < / p> ,
103
+ < p> 这个子节点被放置在 document body 中。 < / p> ,
104
104
document .body
105
105
)}
106
106
< / div>
@@ -117,15 +117,15 @@ export default function MyComponent() {
117
117
< div id= " root" >
118
118
...
119
119
< div style= " border: 2px solid black" >
120
- < p> This child is placed inside the parent div. < / p>
120
+ < p> 这个子节点被放置在父节点 div 中。 < / p>
121
121
< / div>
122
122
...
123
123
< / div>
124
- < p> This child is placed in the document body. < / p>
124
+ < p> 这个子节点被放置在 document body 中。 < / p>
125
125
< / body>
126
126
` ` `
127
127
128
- portal 只改变 DOM 节点的所处位置。另一方面 ,portal 中的 JSX 将作为实际渲染它的 React 组件的子节点。该子节点可以访问由父节点树提供的 context 对象、事件将仍然从子节点冒泡到父节点树。
128
+ portal 只改变 DOM 节点的所处位置。在其他方面 ,portal 中的 JSX 将作为实际渲染它的 React 组件的子节点。该子节点可以访问由父节点树提供的 context 对象、事件将仍然从子节点冒泡到父节点树。
129
129
130
130
---
131
131
@@ -164,7 +164,7 @@ export default function NoPortalExample() {
164
164
return (
165
165
<>
166
166
< button onClick= {() => setShowModal (true )}>
167
- Show modal without a portal
167
+ 不使用 portal 展示模态(modal)
168
168
< / button>
169
169
{showModal && (
170
170
< ModalContent onClose= {() => setShowModal (false )} / >
@@ -184,7 +184,7 @@ export default function PortalExample() {
184
184
return (
185
185
<>
186
186
< button onClick= {() => setShowModal (true )}>
187
- Show modal using a portal
187
+ 使用 portal 展示模态(motal)
188
188
< / button>
189
189
{showModal && createPortal (
190
190
< ModalContent onClose= {() => setShowModal (false )} / > ,
@@ -199,8 +199,8 @@ export default function PortalExample() {
199
199
export default function ModalContent ({ onClose }) {
200
200
return (
201
201
< div className= " modal" >
202
- < div> I ' m a modal dialog </div>
203
- <button onClick={onClose}>Close </button>
202
+ < div> 这是一个模态对话框 < / div>
203
+ < button onClick= {onClose}> 关闭 < / button>
204
204
< / div>
205
205
);
206
206
}
@@ -238,29 +238,29 @@ export default function ModalContent({ onClose }) {
238
238
239
239
<Pitfall>
240
240
241
- 使用 portal 时,确保应用程序的无障碍性非常重要。例如,你可能需要管理键盘焦点,以便用户可以以自然的方式进出 portal。
241
+ 使用 portal 时,确保应用程序的无障碍性非常重要。例如,你可能需要管理键盘焦点,以便用户可以自然进出 portal。
242
242
243
- 创建模态对话框时,请遵循 [WAI-ARIA 模态实践指南](https://www.w3.org/WAI/ARIA/apg/#dialog_modal)。如果你使用了社区包,请确保它是无障碍的 ,并遵循这些指南。
243
+ 创建模态对话框时,请遵循 [WAI-ARIA 模态实践指南](https://www.w3.org/WAI/ARIA/apg/#dialog_modal)。如果你使用了社区包,请确保它具有无障碍性 ,并遵循这些指南。
244
244
245
245
</Pitfall>
246
246
247
247
---
248
248
249
249
### 将 React 组件渲染到非 React 服务器标记中 {/*rendering-react-components-into-non-react-server-markup*/}
250
250
251
- 如果你在静态或服务端渲染的网站中只有某一部分使用 React,则 portal 可能非常有用。如果你的页面使用 Rails 等服务端框架构建,则可以在静态区域(例如侧边栏)中创建交互区域。与拥有 [多个独立的 React 根](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) 相比,portal 将应用程序视为具有共享状态的单个 React 树,即使其部分呈现到 DOM 的不同部分也是如此 。
251
+ 如果静态或服务端渲染的网站中只有某一部分使用 React,则 portal 可能非常有用。如果你的页面使用 Rails 等服务端框架构建,则可以在静态区域(例如侧边栏)中创建交互区域。与拥有 [多个独立的 React 根](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) 相比,portal 将应用程序视为一个单一的 React 树,即使它的部分在 DOM 的不同部分渲染,也可以共享状态 。
252
252
253
253
<Sandpack>
254
254
255
255
` ` ` html index .html
256
256
< ! DOCTYPE html>
257
257
< html>
258
- <head><title>My app </title></head>
258
+ < head>< title> 我的应用程序 < / title>< / head>
259
259
< body>
260
- <h1>Welcome to my hybrid app </h1>
260
+ < h1> 我的网站一部分使用了 React,另外一部分没有使用 < / h1>
261
261
< div class = " parent" >
262
262
< div class = " sidebar" >
263
- This is server non- React markup
263
+ 这是一个非 React 服务器标记
264
264
< div id= " sidebar-content" >< / div>
265
265
< / div>
266
266
< div id= " root" >< / div>
@@ -301,11 +301,11 @@ export default function App() {
301
301
}
302
302
303
303
function MainContent () {
304
- return <p>This part is rendered by React</p>;
304
+ return < p> 这一部分是被 React 渲染的。 < / p> ;
305
305
}
306
306
307
307
function SidebarContent () {
308
- return <p>This part is also rendered by React! </p>;
308
+ return < p> 这一部分也是被 React 渲染的! < / p> ;
309
309
}
310
310
` ` `
311
311
@@ -344,13 +344,13 @@ p {
344
344
345
345
### 将 React 组件渲染到非 React DOM 节点 {/*rendering-react-components-into-non-react-dom-nodes*/}
346
346
347
- 你还可以使用 portal 来管理在 React 之外管理的 DOM 节点的内容。假设你正在集成非 React 地图小部件,并且想要在弹出窗口中渲染 React 内容。那么请声明一个 `popupContainer` state 变量来存储要渲染到的目标 DOM 节点:
347
+ 你还可以使用 portal 来管理在 React 之外管理的 DOM 节点的内容。假设你正在集成非 React 地图小部件,并且想要在弹出窗口中渲染 React 内容,那么可以声明一个 ` popupContainer` state 变量来存储要渲染到的目标 DOM 节点:
348
348
349
349
` ` ` js
350
350
const [popupContainer , setPopupContainer ] = useState (null );
351
351
` ` `
352
352
353
- 在创建第三方小部件时,请存储由小部件返回的 DOM 节点,以便可以将内容渲染到其中:
353
+ 在创建第三方小部件时,存储由小部件返回的 DOM 节点,以便可以将内容渲染到其中:
354
354
355
355
` ` ` js {5 - 6 }
356
356
useEffect (() => {
@@ -369,7 +369,7 @@ useEffect(() => {
369
369
return (
370
370
< div style= {{ width: 250 , height: 250 }} ref= {containerRef}>
371
371
{popupContainer !== null && createPortal (
372
- <p>Hello from React! </p>,
372
+ < p> 来自 React 的你,你好! < / p> ,
373
373
popupContainer
374
374
)}
375
375
< / div>
@@ -420,7 +420,7 @@ export default function Map() {
420
420
return (
421
421
< div style= {{ width: 250 , height: 250 }} ref= {containerRef}>
422
422
{popupContainer !== null && createPortal (
423
- <p>Hello from React! </p>,
423
+ < p> 来自 React 的你,你好! < / p> ,
424
424
popupContainer
425
425
)}
426
426
< / div>
0 commit comments