From c7e372ca0cc0fc61374af17fb2f8c70a13cb3edc Mon Sep 17 00:00:00 2001 From: hoangtvh Date: Sat, 18 Sep 2021 11:21:23 +0700 Subject: [PATCH] translate Ref and the dom in Advanced Guides part --- content/docs/refs-and-the-dom.md | 109 +++++++++++++++---------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/content/docs/refs-and-the-dom.md b/content/docs/refs-and-the-dom.md index 2b2e209db..9643391c8 100644 --- a/content/docs/refs-and-the-dom.md +++ b/content/docs/refs-and-the-dom.md @@ -10,34 +10,33 @@ redirect_from: - "tips/expose-component-functions.html" - "tips/children-undefined.html" --- +Refs là một cách giúp chúng ta truy cập đến những nút DOM hoặc những phần tử React được tạo ra trong phương thức render. -Refs provide a way to access DOM nodes or React elements created in the render method. +Trong luồng dữ liệu của React, [props](/docs/components-and-props.html) là cách duy nhất để các component cha tương tác với component con. Để cập nhật component con, ta phải re-render nó với các props mới. Tuy nhiên, một số trường hợp buộc ta phải thay đổi thành phần con bên ngoài luồng dữ liệu điển hình của React. Component con được sửa đổi có thể là một instance của một React component, hoặc nó có thể là một DOM element. Với những trường hợp trên, ta có thể xử lý bằng Refs. -In the typical React dataflow, [props](/docs/components-and-props.html) are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch. +### Khi nào sử dụng Refs {#when-to-use-refs} -### When to Use Refs {#when-to-use-refs} +Một vài trường hợp hữu ích để sử dụng refs: -There are a few good use cases for refs: +* Quản lý focus, text selection, hoặc media playback. +* Trigger animation của một element khác. +* Tích hợp những thư viện DOM từ bên thứ ba. -* Managing focus, text selection, or media playback. -* Triggering imperative animations. -* Integrating with third-party DOM libraries. +Tránh sử dụng refs trong trường hợp chúng ta có thể khai báo. -Avoid using refs for anything that can be done declaratively. +Ví dụ, thay vì hiển thị phương thức `open()` và `close()` trong `Dialog` component, thì chúng ta sẽ sử dụng `isOpen` như một prop để xử lý nó. -For example, instead of exposing `open()` and `close()` methods on a `Dialog` component, pass an `isOpen` prop to it. +### Không nên lạm dụng Refs {#dont-overuse-refs} -### Don't Overuse Refs {#dont-overuse-refs} +Chúng ta hay có xu hướng sử dụng Refs để xử lý mọi thử xảy ra trong ứng dụng của mình. Nếu rơi vào trường hợp này, thì lời khuyên là bạn nên dành thời gian để suy nghĩ nhiều hơn về vị trí mà bạn nên đặt State trong hệ thống cập bậc component (Component Hierarchy) của bạn. Thông thường, để rõ ràng nhất, thì vị trí State sẽ được đặt ở cấp bậc cao nhất của Component Hierarchy. Bạn có thể tham khảo thêm hướng dẫn và các ví dụ tại đây [Lifting State Up](/docs/lifting-state-up.html). -Your first inclination may be to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. See the [Lifting State Up](/docs/lifting-state-up.html) guide for examples of this. - -> Note +> Lưu ý > -> The examples below have been updated to use the `React.createRef()` API introduced in React 16.3. If you are using an earlier release of React, we recommend using [callback refs](#callback-refs) instead. +> Những ví dụ bên dưới đã được cập nhật để sử dụng `React.createRef()` API được giới thiệu trong React 16.3. Nếu bạn sử dụng những phiên bản trước, React khuyên bạn nên sử dụng [callback refs](#callback-refs) để thay thế. ### Creating Refs {#creating-refs} -Refs are created using `React.createRef()` and attached to React elements via the `ref` attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component. +Refs được khởi tạo bằng `React.createRef()` và được gắn vào các React element thông qua thuộc tính `ref`. Refs thường được gán cho một element nào đó, tại đó chúng ta có thể tham chiếu đến tất cả các thành phần bên trong nó. ```javascript{4,7} class MyComponent extends React.Component { @@ -51,44 +50,44 @@ class MyComponent extends React.Component { } ``` -### Accessing Refs {#accessing-refs} +### Truy cập Refs {#accessing-refs} -When a ref is passed to an element in `render`, a reference to the node becomes accessible at the `current` attribute of the ref. +Khi một element có chứa ref `render`, chúng ta có thể sử dụng một thuộc tính của ref là `current` để truy cập đến node hiện tại. ```javascript const node = this.myRef.current; ``` -The value of the ref differs depending on the type of the node: +Giá trị tham chiếu khác nhau, phụ thuộc vào loại cuả node: -- When the `ref` attribute is used on an HTML element, the `ref` created in the constructor with `React.createRef()` receives the underlying DOM element as its `current` property. -- When the `ref` attribute is used on a custom class component, the `ref` object receives the mounted instance of the component as its `current`. -- **You may not use the `ref` attribute on function components** because they don't have instances. +- Khi thuộc tính `ref` được sử dụng trong HTML element, `ref` sẽ nhận DOM element bên dưới làm thuộc tính `current` của nó. +- Khi thuộc tính `ref` được sử dụng trong class component tùy chỉnh, `ref` sẽ nhận instance của component làm thuộc tính `current` của nó. +- **Bạn không thể sử dụng thuộc tính `ref` trong function components** vì nó không có instances. -The examples below demonstrate the differences. +Các ví dụ dưới đây chứng minh sự khác biệt: -#### Adding a Ref to a DOM Element {#adding-a-ref-to-a-dom-element} +#### Thêm Ref vào một DOM Element {#adding-a-ref-to-a-dom-element} -This code uses a `ref` to store a reference to a DOM node: +Đoạn code sử dụng `ref` để lưu trữ một tham chiếu đến một DOM node: ```javascript{5,12,22} class CustomTextInput extends React.Component { constructor(props) { super(props); - // create a ref to store the textInput DOM element + // Tạo ra một ref để lưu textInput DOM element this.textInput = React.createRef(); this.focusTextInput = this.focusTextInput.bind(this); } focusTextInput() { // Explicitly focus the text input using the raw DOM API - // Note: we're accessing "current" to get the DOM node + // Note: Chúng ra truy cập đến "current" để lấy DOM node this.textInput.current.focus(); } render() { - // tell React that we want to associate the ref - // with the `textInput` that we created in the constructor + // Nói với React chúng ta muốn liên kết tới ref + // Với `textInput` chúng ta đã tạo ở constructor return (
); @@ -161,13 +160,13 @@ class Parent extends React.Component { } ``` -If you want to allow people to take a `ref` to your function component, you can use [`forwardRef`](/docs/forwarding-refs.html) (possibly in conjunction with [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle)), or you can convert the component to a class. +Nếu bạn muốn cho phép mọi người sử dụng `ref` từ function component của bạn, bạn có thể dùng [`forwardRef`](/docs/forwarding-refs.html) (có thể kết hợp với [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle)), hoặc bạn có thể chuyển đổi component thành class. -You can, however, **use the `ref` attribute inside a function component** as long as you refer to a DOM element or a class component: +Tuy nhiên, bạn có thể **sử dụng thuộc tính `ref` bên trong function component** miễn là bạn tham chiếu đến phần tử DOM hoặc class component: ```javascript{2,3,6,13} function CustomTextInput(props) { - // textInput must be declared here so the ref can refer to it + // textInput phải được khai báo ở đây để ref có thể tham chiếu đến nó const textInput = useRef(null); function handleClick() { @@ -189,25 +188,25 @@ function CustomTextInput(props) { } ``` -### Exposing DOM Refs to Parent Components {#exposing-dom-refs-to-parent-components} +### Hiển thị DOM Refs cho Components cha {#exposing-dom-refs-to-parent-components} -In rare cases, you might want to have access to a child's DOM node from a parent component. This is generally not recommended because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node. +Một số ít trường hợp, bạn muốn có quyền truy cập vào DOM node của element con từ component cha. Nhưng chúng tôi không khuyến khích điều đó vì nó sẽ phá hủy tính đóng gói của component, một số ít nó hữu dụng khi trigger focus hoặc xác định kích thước, vị trí của một DOM node con. -While you could [add a ref to the child component](#adding-a-ref-to-a-class-component), this is not an ideal solution, as you would only get a component instance rather than a DOM node. Additionally, this wouldn't work with function components. +Mặc dù bạn có thể [thêm ref vào component con](#adding-a-ref-to-a-class-component), tuy nhiên đây cũng không phải là một ý tưởng tốt, vì cái bạn nhận được chỉ là một component instance chứ không phải là một DOM node. Ý tưởng này cũng sẽ không hoạt động với function components. -If you use React 16.3 or higher, we recommend to use [ref forwarding](/docs/forwarding-refs.html) for these cases. **Ref forwarding lets components opt into exposing any child component's ref as their own**. You can find a detailed example of how to expose a child's DOM node to a parent component [in the ref forwarding documentation](/docs/forwarding-refs.html#forwarding-refs-to-dom-components). +Nếu bạn sử dụng React 16.3 hoặc các phiên bản mới hơn, chúng tôi gợi ý bạn sử dụng [ref forwarding](/docs/forwarding-refs.html) cho những trường hợp như thế này. **Ref forwarding cho phép các component tham gia hiển thị bất kỳ bản tham chiếu nào của component là con của nó**. Bạn có thể tìm hiểu chi tiết thông qua các ví dụ cách component cha hiển thị DOM node con của nó [tại ref forwarding documentation](/docs/forwarding-refs.html#forwarding-refs-to-dom-components). -If you use React 16.2 or lower, or if you need more flexibility than provided by ref forwarding, you can use [this alternative approach](https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509) and explicitly pass a ref as a differently named prop. +Nếu bạn sử dụng React 16.2 hoặc các phiên bản thấp hơn, hoặc nếu bạn cần sự linh hoạt hơn được cung cấp bởi ref forwarding, bạn có thể sử dụng [cách tiếp cận thay thể này](https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509) và chuyển một tham chiếu dưới dạng tên một prop khác. -When possible, we advise against exposing DOM nodes, but it can be a useful escape hatch. Note that this approach requires you to add some code to the child component. If you have absolutely no control over the child component implementation, your last option is to use [`findDOMNode()`](/docs/react-dom.html#finddomnode), but it is discouraged and deprecated in [`StrictMode`](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage). +Khi có thể, chúng tôi khuyên bạn tránh để lộ các DOM node. Lưu ý rằng cách tiếp cận này yêu cầu bạn thêm một số đoạn code vào component con. Nếu bạn hoàn toàn không kiểm soát được việc triển khai thành phần con, lựa chọn cuối của bạn là sử dụng [`findDOMNode()`](/docs/react-dom.html#finddomnode), nhưng nó không được khuyến khích và không được chấp nhận trong [`StrictMode`](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage). ### Callback Refs {#callback-refs} -React also supports another way to set refs called "callback refs", which gives more fine-grain control over when refs are set and unset. +React cũng hỗ trợ một cách set refs khác gọi là "callback refs", giúp kiểm soát tốt hơn khi set và unset ref. -Instead of passing a `ref` attribute created by `createRef()`, you pass a function. The function receives the React component instance or HTML DOM element as its argument, which can be stored and accessed elsewhere. +Thay vì chuyển thuộc tính `ref` được tạo từ `createRef()`, bạn chuyển nó thành một function. Function này sẽ nhận vào một React component instance hoặc HTML DOM element như một argument của nó, có thể được lưu trữ và truy cập ở một nơi khác. -The example below implements a common pattern: using the `ref` callback to store a reference to a DOM node in an instance property. +Ví dụ dưới đây thực hiện việc sử dụng một `ref` callback để lưu trữ tham chiếu tới một DOM node trong một thuộc tính instance. ```javascript{5,7-9,11-14,19,29,34} class CustomTextInput extends React.Component { @@ -251,9 +250,9 @@ class CustomTextInput extends React.Component { } ``` -React will call the `ref` callback with the DOM element when the component mounts, and call it with `null` when it unmounts. Refs are guaranteed to be up-to-date before `componentDidMount` or `componentDidUpdate` fires. +React sẽ gọi `ref` callback với DOM element khi component mounts, và gọi `null` khi component unmounts. Refs đảm bảo được cập nhật trước khi `componentDidMount` hoặc `componentDidUpdate` khởi chạy. -You can pass callback refs between components like you can with object refs that were created with `React.createRef()`. +Bạn có thể chuyển callback refs giữa những component giống như các đối tượng tham chiếu được tạo bởi `React.createRef()`. ```javascript{4,13} function CustomTextInput(props) { @@ -275,16 +274,16 @@ class Parent extends React.Component { } ``` -In the example above, `Parent` passes its ref callback as an `inputRef` prop to the `CustomTextInput`, and the `CustomTextInput` passes the same function as a special `ref` attribute to the ``. As a result, `this.inputElement` in `Parent` will be set to the DOM node corresponding to the `` element in the `CustomTextInput`. +Trong ví dụ trên, `Parent` sẽ chuyển ref callback dưới dạng một `inputRef` prop tới `CustomTextInput`, và `CustomTextInput` chuyển một function tương tự như một thuộc tính `ref` tới ``. Lúc đó `this.inputElement` ở `Parent` sẽ set DOM node tương ứng với `` element trong `CustomTextInput`. ### Legacy API: String Refs {#legacy-api-string-refs} -If you worked with React before, you might be familiar with an older API where the `ref` attribute is a string, like `"textInput"`, and the DOM node is accessed as `this.refs.textInput`. We advise against it because string refs have [some issues](https://github.com/facebook/react/pull/8333#issuecomment-271648615), are considered legacy, and **are likely to be removed in one of the future releases**. +Nếu bạn đã làm việc với React trước đây, bạn có thể quen thuộc với một API cũ hơn trong đó thuộc tính `ref` là một String, như `"textInput"`, và DOM node được truy cập bằng `this.refs.textInput`. Chúng tôi khuyên bạn nên tránh sử dụng nó vì string refs có [một vài vấn đề](https://github.com/facebook/react/pull/8333#issuecomment-271648615), liên quan đến kế thừa, và **có khả năng bị xóa trong các bản phát hành tiếp theo.**. -> Note +> Lưu ý > -> If you're currently using `this.refs.textInput` to access refs, we recommend using either the [callback pattern](#callback-refs) or the [`createRef` API](#creating-refs) instead. +> Nếu hiên tại bạn đang sử dụng `this.refs.textInput` để truy cập đến refs, chúng tôi khuyên bạn nên sử dụng [callback pattern](#callback-refs) hoặc [`createRef` API](#creating-refs) để thay thế. -### Caveats with callback refs {#caveats-with-callback-refs} +### Cảnh báo với callback refs {#caveats-with-callback-refs} -If the `ref` callback is defined as an inline function, it will get called twice during updates, first with `null` and then again with the DOM element. This is because a new instance of the function is created with each render, so React needs to clear the old ref and set up the new one. You can avoid this by defining the `ref` callback as a bound method on the class, but note that it shouldn't matter in most cases. +Nếu `ref` callback được định nghĩa như một inline function, nó sẽ được gọi 2 lần khi cập nhật, lần thứ 1 có giá trị là `null` và lần thứ 2 là DOM element. Điều này xảy ra bởi vì một instance của function được tạo ra sau mỗi lần render, React cần phải xóa những ref cũ và set up một cái mới. Bạn có thể tránh điều này bằng cách định nghĩa `ref` callback như một method trên class, nhưng nó cũng không quan trọng trong hầu hết các trường hợp.