From a29a0cb34c99bc5aec63548a2e585516fb0e46b8 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Fri, 12 Feb 2021 23:13:15 +0800 Subject: [PATCH 1/3] docs(Advanced guides): Translate Portals --- content/docs/portals.md | 64 ++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/content/docs/portals.md b/content/docs/portals.md index 16e90b2e6..86bb8d65a 100644 --- a/content/docs/portals.md +++ b/content/docs/portals.md @@ -4,21 +4,21 @@ title: Portals permalink: docs/portals.html --- -Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. +Portal 提供一個優秀方法來讓 children 可以 render 到 parent component DOM 樹以外的 DOM 節點。 ```js ReactDOM.createPortal(child, container) ``` -The first argument (`child`) is any [renderable React child](/docs/react-component.html#render), such as an element, string, or fragment. The second argument (`container`) is a DOM element. +第一個參數 (`child`) 是任何[可 render 的 React child](/docs/react-component.html#render),例如 element,string 或者 fragment。第二個參數 (`container`) 則是一個 DOM element。 -## Usage {#usage} +## 使用方式 {#usage} -Normally, when you return an element from a component's render method, it's mounted into the DOM as a child of the nearest parent node: +通常當 component 的 render 方法回傳一個 element 時,此 element 會作為 child 被 mount 進最接近的 parent 節點中: ```js{4,6} render() { - // React mounts a new div and renders the children into it + // React mount 一個新的 div 並將 children render 進去 return (
{this.props.children} @@ -27,12 +27,12 @@ render() { } ``` -However, sometimes it's useful to insert a child into a different location in the DOM: +然而在某些狀況下,將 child 插入不同位置的 DOM 內十分好用: ```js{6} render() { - // React does *not* create a new div. It renders the children into `domNode`. - // `domNode` is any valid DOM node, regardless of its location in the DOM. + // React *不會* 創建新的 div。它會將 children render 進 `domNode` 中。 + // `domNode` 可以是任何在隨意位置的合法 DOM node。 return ReactDOM.createPortal( this.props.children, domNode @@ -40,21 +40,21 @@ render() { } ``` -A typical use case for portals is when a parent component has an `overflow: hidden` or `z-index` style, but you need the child to visually "break out" of its container. For example, dialogs, hovercards, and tooltips. +一個典型的 portal 使用案例是,當 parent component 有 `overflow: hidden` 或者 `z-index` 的樣式時,卻仍需要 child 在視覺上「跳出」其容器的狀況。例如 dialog,hovercard 與 tooltip 都屬於此案例。 -> Note: +> 注意: > -> When working with portals, remember that [managing keyboard focus](/docs/accessibility.html#programmatically-managing-focus) becomes very important. +> 當使用 portal 時,需記得[控管鍵盤 focus](/docs/accessibility.html#programmatically-managing-focus) 會變得非常重要。 > -> For modal dialogs, ensure that everyone can interact with them by following the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal). +> 使用跳窗 dialog 時,應確保每個人都可以依照 [WAI-ARIA Modal 開發規範](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal) 定義的方式與其互動。 -[**Try it on CodePen**](https://codepen.io/gaearon/pen/yzMaBd) +[**在 CodePen 上試試看吧!**](https://codepen.io/gaearon/pen/yzMaBd) -## Event Bubbling Through Portals {#event-bubbling-through-portals} +## 透過 Portal 進行 Event Bubbling {#event-bubbling-through-portals} -Even though a portal can be anywhere in the DOM tree, it behaves like a normal React child in every other way. Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the *React tree* regardless of position in the *DOM tree*. +雖然 portal 可以被放置在 DOM tree 中的任何位置,但 portal 的其他行為與一般的 React child 別無二致。像是 context 等功能的運作方式並不會因為 child 是 portal 而有所不同,因為不論 portal 在 DOM tree 中的位置為何,它都存在於 *React tree* 中。 -This includes event bubbling. An event fired from inside a portal will propagate to ancestors in the containing *React tree*, even if those elements are not ancestors in the *DOM tree*. Assuming the following HTML structure: +相同的行為也包括 event bubbling。一個在 portal 內觸發的 event 會傳遞到涵蓋它的 *React tree* 祖先中,就算涵蓋它的那些 element 並不是 DOM tree 上的祖先。假設存在以下 HTML 結構: ```html @@ -65,10 +65,10 @@ This includes event bubbling. An event fired from inside a portal will propagate ``` -A `Parent` component in `#app-root` would be able to catch an uncaught, bubbling event from the sibling node `#modal-root`. +一個在 `#app-root` 中的 `Parent` component 可以捕捉從 sibling 節點 `#modal-root` bubble 上來且未被接收過的 event。 ```js{28-31,42-49,53,61-63,70-71,74} -// These two containers are siblings in the DOM +// 這兩個 container 是 DOM 上的 sibling const appRoot = document.getElementById('app-root'); const modalRoot = document.getElementById('modal-root'); @@ -79,14 +79,13 @@ class Modal extends React.Component { } componentDidMount() { - // The portal element is inserted in the DOM tree after - // the Modal's children are mounted, meaning that children - // will be mounted on a detached DOM node. If a child - // component requires to be attached to the DOM tree - // immediately when mounted, for example to measure a - // DOM node, or uses 'autoFocus' in a descendant, add - // state to Modal and only render the children when Modal - // is inserted in the DOM tree. + // Portal element 會在 Modal 的 children 被 + // mount 之後才插入 DOM tree 中,這代表 children + // 會被 mount 在一個分離的 DOM 節點上。如果一個 + // child component 需要在 mount 結束時馬上連接到 DOM tree 中, + // 例如測量一個 DOM node,或者在子節點中使用 'autoFocus' 等狀況, + // 則應將 state 加入 Modal 中,並只在 Modal 插入 DOM tree 後 + // 才 render children。 modalRoot.appendChild(this.el); } @@ -110,9 +109,8 @@ class Parent extends React.Component { } handleClick() { - // This will fire when the button in Child is clicked, - // updating Parent's state, even though button - // is not direct descendant in the DOM. + // 這會在 Child 中的 button 被點擊時觸發並更新 Parent 的 state, + // 就算 Child 的 button 並不是 DOM 中的直接後代。 this.setState(state => ({ clicks: state.clicks + 1 })); @@ -137,8 +135,8 @@ class Parent extends React.Component { } function Child() { - // The click event on this button will bubble up to parent, - // because there is no 'onClick' attribute defined + // 這個 button 中的 click event 會被 bubble 到 parent 中, + // 因為這邊並沒有定義 'onClick' attribute return (
@@ -149,6 +147,6 @@ function Child() { ReactDOM.render(, appRoot); ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/jGBWpE) +[**在 CodePen 上試試看吧!**](https://codepen.io/gaearon/pen/jGBWpE) -Catching an event bubbling up from a portal in a parent component allows the development of more flexible abstractions that are not inherently reliant on portals. For example, if you render a `` component, the parent can capture its events regardless of whether it's implemented using portals. +Parent component 可以捕捉從 portal bubble 上來的 event 能使開發具有不直接依賴於 portal 的更彈性化抽象性。舉例來說,如果你 render 了一個 `` component,則不論 Modal 是否是使用 portal 實作,它的 parent 皆可以捕捉到其 event。 From e057eaf5c3dc068570cdf76c028ddb483a462c37 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Fri, 12 Feb 2021 23:28:35 +0800 Subject: [PATCH 2/3] docs(Advanced guides): Change title Portals to Portal --- content/docs/portals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/portals.md b/content/docs/portals.md index 86bb8d65a..834c2ad88 100644 --- a/content/docs/portals.md +++ b/content/docs/portals.md @@ -1,6 +1,6 @@ --- id: portals -title: Portals +title: Portal permalink: docs/portals.html --- From ebd1a3ba561d488ab143b43a729784784200b800 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 18 Feb 2021 09:11:12 +0800 Subject: [PATCH 3/3] docs(Advanced guides): Fix wordings, white spaces in portal --- content/docs/portals.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/docs/portals.md b/content/docs/portals.md index 834c2ad88..a191b8504 100644 --- a/content/docs/portals.md +++ b/content/docs/portals.md @@ -10,7 +10,7 @@ Portal 提供一個優秀方法來讓 children 可以 render 到 parent componen ReactDOM.createPortal(child, container) ``` -第一個參數 (`child`) 是任何[可 render 的 React child](/docs/react-component.html#render),例如 element,string 或者 fragment。第二個參數 (`container`) 則是一個 DOM element。 +第一個參數(`child`)是任何[可 render 的 React child](/docs/react-component.html#render),例如 element、string 或者 fragment。第二個參數(`container`)則是一個 DOM element。 ## 使用方式 {#usage} @@ -31,7 +31,7 @@ render() { ```js{6} render() { - // React *不會* 創建新的 div。它會將 children render 進 `domNode` 中。 + // React *不會*建立新的 div。它會將 children render 進 `domNode` 中。 // `domNode` 可以是任何在隨意位置的合法 DOM node。 return ReactDOM.createPortal( this.props.children, @@ -40,11 +40,11 @@ render() { } ``` -一個典型的 portal 使用案例是,當 parent component 有 `overflow: hidden` 或者 `z-index` 的樣式時,卻仍需要 child 在視覺上「跳出」其容器的狀況。例如 dialog,hovercard 與 tooltip 都屬於此案例。 +一個典型的 portal 使用案例是,當 parent component 有 `overflow: hidden` 或者 `z-index` 的樣式時,卻仍需要 child 在視覺上「跳出」其容器的狀況。例如 dialog、hovercard 與 tooltip 都屬於此案例。 > 注意: > -> 當使用 portal 時,需記得[控管鍵盤 focus](/docs/accessibility.html#programmatically-managing-focus) 會變得非常重要。 +> 當使用 portal 時,請留意[控管鍵盤 focus](/docs/accessibility.html#programmatically-managing-focus) 對於無障礙功能會變得非常重要。 > > 使用跳窗 dialog 時,應確保每個人都可以依照 [WAI-ARIA Modal 開發規範](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal) 定義的方式與其互動。