From 8d751bfaf89dd3a7cc2b7a43769eeeba80c3e00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C6=B0u=20B=C3=ACnh=20An?= Date: Wed, 3 Jul 2019 16:52:53 +0700 Subject: [PATCH 1/5] translate using effect hook --- content/docs/hooks-effect.md | 188 ++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 93 deletions(-) diff --git a/content/docs/hooks-effect.md b/content/docs/hooks-effect.md index 142dd6756..87753ad75 100644 --- a/content/docs/hooks-effect.md +++ b/content/docs/hooks-effect.md @@ -1,14 +1,14 @@ --- id: hooks-state -title: Using the Effect Hook +title: Sử dụng Effect Hook permalink: docs/hooks-effect.html next: hooks-rules.html prev: hooks-state.html --- -*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. +*Hook* là một tính năng mới từ React 16.8. Nó cho phép sử dụng state và các tính năng khác của React mà không cần viết dạng class -The *Effect Hook* lets you perform side effects in function components: +*Effect Hook* cho phép thực hiện side effect bên trong các function component: ```js{1,6-10} import React, { useState, useEffect } from 'react'; @@ -16,9 +16,9 @@ import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); - // Similar to componentDidMount and componentDidUpdate: + // Tương tự như componentDidMount và componentDidUpdate: useEffect(() => { - // Update the document title using the browser API + // Cập nhập document title sử dụng browser API document.title = `You clicked ${count} times`; }); @@ -33,25 +33,25 @@ function Example() { } ``` -This snippet is based on the [counter example from the previous page](/docs/hooks-state.html), but we added a new feature to it: we set the document title to a custom message including the number of clicks. +Đoạn snippet này dựa trên [ví dụ về counter ở trang trước](/docs/hooks-state.html), chúng ta có thêm tính năng mới: đặt giá trị document title tương ứng với số lần click. -Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. Whether or not you're used to calling these operations "side effects" (or just "effects"), you've likely performed them in your components before. +Fetching data, thiết lập các subscription, và tự ý thay đổi DOM trong React component, những hành động như vậy được là "side effect" (hoặc "effect"). >Tip > ->If you're familiar with React class lifecycle methods, you can think of `useEffect` Hook as `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` combined. +>Nếu bạn quen với các phương thức lifecycle của React class, bạn có thể hình dung `useEffect` Hook như sự kết hợp của `componentDidMount`, `componentDidUpdate`, và `componentWillUnmount`. -There are two common kinds of side effects in React components: those that don't require cleanup, and those that do. Let's look at this distinction in more detail. +Có 2 loại side effect phổ biến trong React component: loại không cần cleanup, và loại cần. Cùng phân biệt 2 loại này kỹ hơn. -## Effects Without Cleanup {#effects-without-cleanup} +## Effect không cần Cleanup {#effects-without-cleanup} -Sometimes, we want to **run some additional code after React has updated the DOM.** Network requests, manual DOM mutations, and logging are common examples of effects that don't require a cleanup. We say that because we can run them and immediately forget about them. Let's compare how classes and Hooks let us express such side effects. +Đôi lúc, chúng ta muốn **chạy một vài đoạn code sau khi React đã cập nhập DOM.** Network request, tự ý thay đổi DOM, và logging là những ví dụ điển hình của effect không cần cleanup. Chúng ta gọi như vậy vì có thể chạy chúng và quên ngay lập tức. Hãy so sánh class và Hook cho phép thực hiện side effect như thế ra sao. -### Example Using Classes {#example-using-classes} +### Ví dụ sử dụng Classes {#example-using-classes} -In React class components, the `render` method itself shouldn't cause side effects. It would be too early -- we typically want to perform our effects *after* React has updated the DOM. +Trong React class components, phương thức `render` không được phép tạo ra side effect. Nó sẽ là quá sớm -- chúng ta thường chỉ muốn chạy effect *sau khi* React đã cập nhập DOM. -This is why in React classes, we put side effects into `componentDidMount` and `componentDidUpdate`. Coming back to our example, here is a React counter class component that updates the document title right after React makes changes to the DOM: +Đó là lý do tại sao trong React class, chúng ta đặt side effect bên trong `componentDidMount` và `componentDidUpdate`. Quay lại ví dụ, đây là React counter class component sẽ cập nhập document title ngay sau khi React thay đổi DOM: ```js{9-15} class Example extends React.Component { @@ -83,15 +83,15 @@ class Example extends React.Component { } ``` -Note how **we have to duplicate the code between these two lifecycle methods in class.** +Để ý cách **chúng ta đã lập lại 2 thao tác tương tự nhau bên trong 2 phương thức lifecycle** -This is because in many cases we want to perform the same side effect regardless of whether the component just mounted, or if it has been updated. Conceptually, we want it to happen after every render -- but React class components don't have a method like this. We could extract a separate method but we would still have to call it in two places. +Đó là bởi vì trong đa phần các trường hợp, chúng ta muốn thực hiện cùng một side effect khi component đã mount hoặc đã update. Một cách tổng quát, chúng ta muốn thực hiện sau mỗi lần render -- nhưng React class component không có phương thức như vậy. Chúng ta có thể tách nó ra thành một hàm riêng, nhưng vẫn phải gọi nó ở 2 nơi khác nhau. -Now let's see how we can do the same with the `useEffect` Hook. +Bây giờ chúng ta xem cách làm tương tự với `useEffect` Hook. -### Example Using Hooks {#example-using-hooks} +### Ví dụ sử dụng Hook {#example-using-hooks} -We've already seen this example at the top of this page, but let's take a closer look at it: +Chúng ta đã xem ví dụ ở trên, giờ xem kỹ hơn một lần nữa: ```js{1,6-8} import React, { useState, useEffect } from 'react'; @@ -114,15 +114,15 @@ function Example() { } ``` -**What does `useEffect` do?** By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we'll refer to it as our "effect"), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API. +**`useEffect` đã làm gì?** Bằng cách sử dụng Hook này, chúng ta nói với React rằng component của chúng ta cần thực hiện một việc gì đó sau khi render. React sẽ ghi nhớ hàm bạn truyền vào (chúng tôi thích gọi nó là "effect"), và sau đó gọi lại hàm này sau khi DOM đã update. Trong effect này, chúng ta đổi document title, chúng ta cũng có thể fetch data hoặc gọi một số API khác. -**Why is `useEffect` called inside a component?** Placing `useEffect` inside the component lets us access the `count` state variable (or any props) right from the effect. We don't need a special API to read it -- it's already in the function scope. Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution. +**Tại sao `useEffect` được gọi bên trong component?** Đặt `useEffect` bên trong component cho phép chúng ta truy xuất đến state `count` (hoặc bất kỳ prop nào) bên trong effect. Chúng ta không cần một API đặc biệt để đọc nó -- nó đã nằm trong scope của function. Hook tận dụng JavaScript closures và tránh cung cấp thêm các APIs mà bản thân JavaScript đã có sẵn giải pháp. -**Does `useEffect` run after every render?** Yes! By default, it runs both after the first render *and* after every update. (We will later talk about [how to customize this](#tip-optimizing-performance-by-skipping-effects).) Instead of thinking in terms of "mounting" and "updating", you might find it easier to think that effects happen "after render". React guarantees the DOM has been updated by the time it runs the effects. +**`useEffect` chạy sau tất cả những lần render?** Đúng! Theo mặc định, nó chạy sau lần render đầu tiên *và* mỗi lần update. (Chúng ta sẽ nói về [làm cách nào để tùy biến lại](#tip-optimizing-performance-by-skipping-effects).) Thay vì nghĩ theo hướng "mounting" và "updating", bạn sẽ thấy dễ hiểu hơn nếu nghĩ theo kiểu "sau khi render". React đảm bảo DOM đã được update trước khi chạy effect. -### Detailed Explanation {#detailed-explanation} +### Giải thích cụ thể {#detailed-explanation} -Now that we know more about effects, these lines should make sense: +Giờ chúng ta đã hiểu về effect, đoạn code này sẽ rất dễ hiểu: ```js function Example() { @@ -133,21 +133,21 @@ function Example() { }); ``` -We declare the `count` state variable, and then we tell React we need to use an effect. We pass a function to the `useEffect` Hook. This function we pass *is* our effect. Inside our effect, we set the document title using the `document.title` browser API. We can read the latest `count` inside the effect because it's in the scope of our function. When React renders our component, it will remember the effect we used, and then run our effect after updating the DOM. This happens for every render, including the first one. +Chúng ta khai báo state `count`, và sau đó nói với React chúng ta cần sử dụng. Chúng ta truyền cho `useEffect` Hook một hàm. Hàm truyền vào này *là* effect. Bên trong effect, chúng ta đặt document title sử dụng API `document.title`. Chúng ta có thể đọc giá trị sau cùng của `count` bên trong effect bởi vì nó nằm chung scope với function. Khi React render component, nó sẽ nhớ lại effect chúng ta đã gửi, và chạy effect sau khi cập nhập DOM. Nó xảy ra ở tất cả các lần render, kể cả lần đầu. -Experienced JavaScript developers might notice that the function passed to `useEffect` is going to be different on every render. This is intentional. In fact, this is what lets us read the `count` value from inside the effect without worrying about it getting stale. Every time we re-render, we schedule a _different_ effect, replacing the previous one. In a way, this makes the effects behave more like a part of the render result -- each effect "belongs" to a particular render. We will see more clearly why this is useful [later on this page](#explanation-why-effects-run-on-each-update). +Lập trình viên JavaScript có kinh nghiệm sẽ để ý thấy function truyền vào cho `useEffect` sẽ khác nhau cho tất cả các lần render. Đây là điều cố ý. Thật ra, nó sẽ cho chúng ta đọc giá trị `count` bên trong effect mà không cần lo lắng về việc lấy state. Mỗi lần chúng ta re-render, chúng ta gọi một effect **khác**, thay thế cái trước đó. Bằng cách này, nó làm cho effect như một phần của việc render -- mỗi effect "thuộc vào" một render cụ thể. Chúng ta sẽ hiểu tại sao cách này lại hiệu quả [ở phần sau của bài này](#explanation-why-effects-run-on-each-update). >Tip > ->Unlike `componentDidMount` or `componentDidUpdate`, effects scheduled with `useEffect` don't block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don't need to happen synchronously. In the uncommon cases where they do (such as measuring the layout), there is a separate [`useLayoutEffect`](/docs/hooks-reference.html#uselayouteffect) Hook with an API identical to `useEffect`. +>Không giống `componentDidMount` hoặc `componentDidUpdate`, effect chạy với `useEffect` không block trình duyệt cập nhập màn hình. Các effect chủ yếu không cần xảy ra tuần tự. Trong vài tình huống không mấy phổ biến (ví dụ như đo layout), chúng ta có [`useLayoutEffect`](/docs/hooks-reference.html#uselayouteffect) Hook với API tính năng tương tự như `useEffect`. -## Effects with Cleanup {#effects-with-cleanup} +## Effect cần Cleanup {#effects-with-cleanup} -Earlier, we looked at how to express side effects that don't require any cleanup. However, some effects do. For example, **we might want to set up a subscription** to some external data source. In that case, it is important to clean up so that we don't introduce a memory leak! Let's compare how we can do it with classes and with Hooks. +Ở trên, chúng ta đã bàn về những side effect không cần cleanup. Tuy nhiên, một vài effect cần có. Ví dụ, **chúng ta muốn thiết lập các subscription** cho vài data source bên ngoài. Tình huống đó, clean up là rất quan trọng để không xảy ra memory leak! Cùng so sánh cách làm giữa class và Hook -### Example Using Classes {#example-using-classes-1} +### Ví dụ sử dụng Class {#example-using-classes-1} -In a React class, you would typically set up a subscription in `componentDidMount`, and clean it up in `componentWillUnmount`. For example, let's say we have a `ChatAPI` module that lets us subscribe to a friend's online status. Here's how we might subscribe and display that status using a class: +Trong React class, chúng ta thường cài đặt một subscription trong `componentDidMount`, và clean it up trong `componentWillUnmount`. Lấy ví dụ, chúng ta có `ChatAPI` module cho phép chúng ta subscribe vào tình trạng online của 1 danh sách friend. Cách chúng ta làm với class ```js{8-26} class FriendStatus extends React.Component { @@ -186,17 +186,17 @@ class FriendStatus extends React.Component { } ``` -Notice how `componentDidMount` and `componentWillUnmount` need to mirror each other. Lifecycle methods force us to split this logic even though conceptually code in both of them is related to the same effect. +Để ý `componentDidMount` và `componentWillUnmount`. Phương thức Lifecycle buộc chúng ta tách logic này ra thậm chí cả 2 đoạn code trên điều liên quan đến cùng một effect. ->Note +>Lưu ý > ->Eagle-eyed readers may notice that this example also needs a `componentDidUpdate` method to be fully correct. We'll ignore this for now but will come back to it in a [later section](#explanation-why-effects-run-on-each-update) of this page. +>Nếu để ý kỹ hơn, bạn sẽ thấy chúng ta còn cần thêm `componentDidUpdate` để thực sự chuẩn xác. Tạm thời cứ bỏ qua phần đó vì chúng ta sẽ đề cập lại [ở phần sau](#explanation-why-effects-run-on-each-update) of this page. -### Example Using Hooks {#example-using-hooks-1} +### Ví dụ sử dụng Hooks {#example-using-hooks-1} -Let's see how we could write this component with Hooks. +Cùng xem cách chúng ta làm với Hook. -You might be thinking that we'd need a separate effect to perform the cleanup. But code for adding and removing a subscription is so tightly related that `useEffect` is designed to keep it together. If your effect returns a function, React will run it when it is time to clean up: +Bạn có thể sẽ nghĩ chúng ta cần 2 effect khác nhau để thực hiện cleanup. Code khởi tạo và xóa subscription luôn luôn đứng kề nhau, `useEffect` được thiết kế để dữ chúng cùng một chỗ. Nếu effect trả về function, React sẽ chạy function đó, chúng ta đưa clean up vào bên trong function trả về: ```js{6-16} import React, { useState, useEffect } from 'react'; @@ -210,7 +210,7 @@ function FriendStatus(props) { } ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); - // Specify how to clean up after this effect: + // Chỉ định clean up sau khi gọi effect: return function cleanup() { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; @@ -223,17 +223,17 @@ function FriendStatus(props) { } ``` -**Why did we return a function from our effect?** This is the optional cleanup mechanism for effects. Every effect may return a function that cleans up after it. This lets us keep the logic for adding and removing subscriptions close to each other. They're part of the same effect! +**Tại sao chúng ta trả về function bên trong effect?** Đây là một tùy chọn để chạy cơ chế cleanup cho effect. Nó cho phép chúng ta đưa tạo và xóa subscription trong cùng một effect. -**When exactly does React clean up an effect?** React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React *also* cleans up effects from the previous render before running the effects next time. We'll discuss [why this helps avoid bugs](#explanation-why-effects-run-on-each-update) and [how to opt out of this behavior in case it creates performance issues](#tip-optimizing-performance-by-skipping-effects) later below. +**Khi nào React clean up một effect?** React thực hiện cleanup khi component unmount. Tuy nhiên, như đã học trước đó, effect trên tất cả những lần render, không phải chỉ một. Đó là tại sao React *đồng thời* cleans up effect từ những lần render trước. Chúng ta sẽ thảo luận thêm [việc này giúp tránh bug](#explanation-why-effects-run-on-each-update) và [làm cách nào tùy biến đặc tính này để cái thiện performance ](#tip-optimizing-performance-by-skipping-effects) ở bên dưới. ->Note +>Ghi chú > ->We don't have to return a named function from the effect. We called it `cleanup` here to clarify its purpose, but you could return an arrow function or call it something different. +>Chúng ta không cần trả về một function có tên trong effect. Chúng ta gọi nó là `cleanup` để chỉ rõ mục đích, bạn có thể dùng arrow function trong thực tế. -## Recap {#recap} +## Tổng hợp {#recap} -We've learned that `useEffect` lets us express different kinds of side effects after a component renders. Some effects might require cleanup so they return a function: +Chúng ta đã học `useEffect` cho phép chúng ta thực hiện nhiều kiểu side effect sau khi component được render. Một vài effect cần cleanup nó sẽ return một function: ```js useEffect(() => { @@ -248,7 +248,7 @@ We've learned that `useEffect` lets us express different kinds of side effects a }); ``` -Other effects might not have a cleanup phase, and don't return anything. +Một vài effect khác có thể không cần cleanup, thì không cần return gì cả. ```js useEffect(() => { @@ -256,21 +256,21 @@ Other effects might not have a cleanup phase, and don't return anything. }); ``` -The Effect Hook unifies both use cases with a single API. +Effect Hook được sử dụng trong cả 2 trường hợp. ------------- -**If you feel like you have a decent grasp on how the Effect Hook works, or if you feel overwhelmed, you can jump to the [next page about Rules of Hooks](/docs/hooks-rules.html) now.** +**Nếu bạn đã nắm bắt được cách làm việc của Effect Hook, hoặc nếu bạn cảm thấy hơi ngợp, có thể nhảy xuống [phần Nguyên tắc sử dụng Hook](/docs/hooks-rules.html) bây giờ.** ------------- -## Tips for Using Effects {#tips-for-using-effects} +## Tip sử dụng Effect {#tips-for-using-effects} -We'll continue this page with an in-depth look at some aspects of `useEffect` that experienced React users will likely be curious about. Don't feel obligated to dig into them now. You can always come back to this page to learn more details about the Effect Hook. +Chúng ta sẽ cùng đi sâu một số khía cạnh của `useEffect` mà các lập trình viên React có kinh nghiệm sẽ thắc mắc. Không cần quá cưỡng ép bản thân, bạn có thể dừng ở đây, và quay lại để tìm hiểu Effect Hook bất cứ lúc nào. -### Tip: Use Multiple Effects to Separate Concerns {#tip-use-multiple-effects-to-separate-concerns} +### Tip: Sử dụng nhiều Effect tách biệt{#tip-use-multiple-effects-to-separate-concerns} -One of the problems we outlined in the [Motivation](/docs/hooks-intro.html#complex-components-become-hard-to-understand) for Hooks is that class lifecycle methods often contain unrelated logic, but related logic gets broken up into several methods. Here is a component that combines the counter and the friend status indicator logic from the previous examples: +Một trong những vấn đề đã liệt kê ở [động lực](/docs/hooks-intro.html#complex-components-become-hard-to-understand) tạo ra Hooks là các phương thức lifecycle của class thường chứa những logic không liên quan với nhau, còn những logic đáng lý phải nằm gần nhau lại nằm ở các phương thức khác nhau. Đây là component kết hợp counter và friend status từ ví dụ ở trên ```js class FriendStatusWithCounter extends React.Component { @@ -307,9 +307,9 @@ class FriendStatusWithCounter extends React.Component { // ... ``` -Note how the logic that sets `document.title` is split between `componentDidMount` and `componentDidUpdate`. The subscription logic is also spread between `componentDidMount` and `componentWillUnmount`. And `componentDidMount` contains code for both tasks. +Để ý cái logic của `document.title` đang nằm ở `componentDidMount` và `componentDidUpdate`. Logic của subscription thì cũng nằm ở `componentDidMount` và `componentWillUnmount`. Và `componentDidMount` chứa code cả hai. -So, how can Hooks solve this problem? Just like [you can use the *State* Hook more than once](/docs/hooks-state.html#tip-using-multiple-state-variables), you can also use several effects. This lets us separate unrelated logic into different effects: +Như vậy hook đã giải quyết vấn đề này như thế nào? Nếu như [bạn có thể sử dụng *State* Hook nhiều lần](/docs/hooks-state.html#tip-using-multiple-state-variables), bạn cũng có thể sử dụng nhiều effect. Nó cho phép tách những logic không liên quan ra thành những effect khác nhau: ```js{3,8} function FriendStatusWithCounter(props) { @@ -333,13 +333,13 @@ function FriendStatusWithCounter(props) { } ``` -**Hooks let us split the code based on what it is doing** rather than a lifecycle method name. React will apply *every* effect used by the component, in the order they were specified. +**Hook cho phép tách code dựa trên cái nó đang làm** chứ không đi theo phương thức lifecycle. React sẽ apply *từng* effect được sử dụng trong component, theo thứ tự đã khai báo. -### Explanation: Why Effects Run on Each Update {#explanation-why-effects-run-on-each-update} +### Giải thích: Tại sao Effect chạy trên mỗi update {#explanation-why-effects-run-on-each-update} -If you're used to classes, you might be wondering why the effect cleanup phase happens after every re-render, and not just once during unmounting. Let's look at a practical example to see why this design helps us create components with fewer bugs. +Nếu đã từng sử dụng class, bạn sẽ thắc mắc tại sao bước cleanup effect lại chạy trên mỗi lần re-render, mà không phải khi unmounting. Xét một ví dụ thực tế để thấy tại sao thiết kế này giúp chúng ta có những component ít bug hơn -[Earlier on this page](#example-using-classes-1), we introduced an example `FriendStatus` component that displays whether a friend is online or not. Our class reads `friend.id` from `this.props`, subscribes to the friend status after the component mounts, and unsubscribes during unmounting: +[Ở phần trước](#example-using-classes-1), chúng ta có đề cập ví dụ `FriendStatus` để hiển thị trạng thái online của Friend. Class đọc `friend.id` từ `this.props`, subscribe sau khi component mount, và unsubscribe trong lúc unmounting: ```js componentDidMount() { @@ -357,9 +357,9 @@ If you're used to classes, you might be wondering why the effect cleanup phase h } ``` -**But what happens if the `friend` prop changes** while the component is on the screen? Our component would continue displaying the online status of a different friend. This is a bug. We would also cause a memory leak or crash when unmounting since the unsubscribe call would use the wrong friend ID. +**Chuyện gì sẽ xảy ra nếu prop `friend` thay đổi** trong khi component đang hiển thị trên màn hình (chưa unmount)? Chắc chắn có bug với danh sách status. Chúng ta cũng có thể gây ra memory leak hoặc crash khi đang unmounting và gọi unsubscribe nếu có một Friend ID không đúng. -In a class component, we would need to add `componentDidUpdate` to handle this case: +Trong class component, chúng ta cần thêm `componentDidUpdate` để xử lý tình huống này: ```js{8-19} componentDidMount() { @@ -370,12 +370,12 @@ In a class component, we would need to add `componentDidUpdate` to handle this c } componentDidUpdate(prevProps) { - // Unsubscribe from the previous friend.id + // Unsubscribe friend.id trước đó ChatAPI.unsubscribeFromFriendStatus( prevProps.friend.id, this.handleStatusChange ); - // Subscribe to the next friend.id + // Subscribe friend.id mới ChatAPI.subscribeToFriendStatus( this.props.friend.id, this.handleStatusChange @@ -390,9 +390,9 @@ In a class component, we would need to add `componentDidUpdate` to handle this c } ``` -Forgetting to handle `componentDidUpdate` properly is a common source of bugs in React applications. +Quên handle `componentDidUpdate` là điều dễ dẫn tới có bug trong React. -Now consider the version of this component that uses Hooks: +Đây là phiên bản sử dụng Hook ```js function FriendStatus(props) { @@ -406,31 +406,31 @@ function FriendStatus(props) { }); ``` -It doesn't suffer from this bug. (But we also didn't make any changes to it.) +Không còn bị dính bug như ở trên -There is no special code for handling updates because `useEffect` handles them *by default*. It cleans up the previous effects before applying the next effects. To illustrate this, here is a sequence of subscribe and unsubscribe calls that this component could produce over time: +Sẽ không có một đoạn code nào đặc biệt để xử lý lúc update vì theo cách chạy *mặc định* của `useEffect` nó đã xóa effect trước khi apply effect mới. Để hình dung hóa, đây là các bước gọi subscribe và unsubscribe mà component đã chạy qua: ```js -// Mount with { friend: { id: 100 } } props -ChatAPI.subscribeToFriendStatus(100, handleStatusChange); // Run first effect +// Mount với prop { friend: { id: 100 } } +ChatAPI.subscribeToFriendStatus(100, handleStatusChange); // Chạy effect đầu tiên -// Update with { friend: { id: 200 } } props -ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // Clean up previous effect -ChatAPI.subscribeToFriendStatus(200, handleStatusChange); // Run next effect +// Cập nhập prop { friend: { id: 200 } } +ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // Clean effect trước đó +ChatAPI.subscribeToFriendStatus(200, handleStatusChange); // Chạy effect tiếp theo -// Update with { friend: { id: 300 } } props -ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // Clean up previous effect -ChatAPI.subscribeToFriendStatus(300, handleStatusChange); // Run next effect +// Cập nhập với { friend: { id: 300 } } +ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // Clean effect trước đó +ChatAPI.subscribeToFriendStatus(300, handleStatusChange); // Chạy effect tiếp theo // Unmount -ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // Clean up last effect +ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // Clean effect lần cuối ``` -This behavior ensures consistency by default and prevents bugs that are common in class components due to missing update logic. +Đặc tính này đảm bảo thống nhất và ngăn bug thường xuất hiện do không cập nhập login với class component -### Tip: Optimizing Performance by Skipping Effects {#tip-optimizing-performance-by-skipping-effects} +### Tip: Tối ưu Performance bằng cách bỏ qua Effect {#tip-optimizing-performance-by-skipping-effects} -In some cases, cleaning up or applying the effect after every render might create a performance problem. In class components, we can solve this by writing an extra comparison with `prevProps` or `prevState` inside `componentDidUpdate`: +Trong một số trường hợp, clean và apply effect sau khi render có thể dẫn đến ảnh hưởng performance. Trong class component, chúng ta giải quyết bằng viết một hàm so sánh giữa `prevProps` hoặc `prevState` bên trong `componentDidUpdate`: ```js componentDidUpdate(prevProps, prevState) { @@ -440,19 +440,19 @@ componentDidUpdate(prevProps, prevState) { } ``` -This requirement is common enough that it is built into the `useEffect` Hook API. You can tell React to *skip* applying an effect if certain values haven't changed between re-renders. To do so, pass an array as an optional second argument to `useEffect`: +Đây là yêu cầu rất cần thiết, nên đã được có đưa sẵn trong `useEffect` Hook API. Bạn có thể bảo React *bỏ qua* việc apply effect nếu một số giá trị không thay đổi giữa các lần render. Để làm như vậy, truyền vào một array (không bắt buộc) vào `useEffect`: ```js{3} useEffect(() => { document.title = `You clicked ${count} times`; -}, [count]); // Only re-run the effect if count changes +}, [count]); // Chỉ re-run effect nếu giá trị count thay đổi ``` -In the example above, we pass `[count]` as the second argument. What does this mean? If the `count` is `5`, and then our component re-renders with `count` still equal to `5`, React will compare `[5]` from the previous render and `[5]` from the next render. Because all items in the array are the same (`5 === 5`), React would skip the effect. That's our optimization. +Trong ví dụ ở trên, chúng ta truyền vào `[count]` như một tham số thứ 2. Nó nghĩa là gì? Nếu `count` là `5`, rồi sau đó component re-render với `count` vẫn bằng `5`, React sẽ so sánh `[5]` từ lần render trước và `[5]` với lần render hiện tại. Vì tất cả giá trị trong mảng bằng nhau (`5 === 5`), React sẽ bỏ qua effect. Đó là cách chúng ta tối ưu -When we render with `count` updated to `6`, React will compare the items in the `[5]` array from the previous render to items in the `[6]` array from the next render. This time, React will re-apply the effect because `5 !== 6`. If there are multiple items in the array, React will re-run the effect even if just one of them is different. +Khi chúng ta render với `count` thành `6`, React sẽ so sánh các giá trị trong `[5]` từ lần render trước với các giá trị trong `[6]` lần render hiện tại. Ở lần này, React sẽ gọi lại effect vì `5 !== 6`. Nếu có nhiều giá trị bên trong array, React sẽl re-run effect nếu một trong các giá trị đó khác với lần trước. -This also works for effects that have a cleanup phase: +Effect cũng làm việc tương tự với quá trình cleanup: ```js{10} useEffect(() => { @@ -464,25 +464,27 @@ useEffect(() => { return () => { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; -}, [props.friend.id]); // Only re-subscribe if props.friend.id changes +}, [props.friend.id]); // Chỉ re-subscribe nếu props.friend.id bị thay đổi ``` -In the future, the second argument might get added automatically by a build-time transformation. +Trong tương lai, tham số thứ 2 sẽ được tự động thêm vào trong lúc build-transform. ->Note +>Lưu ý > ->If you use this optimization, make sure the array includes **all values from the component scope (such as props and state) that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and [what to do when the array changes too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often). +>Nếu sử dụng cách tối ưu này, phải chắc chắn array chứa **tất cả giá trị bên trong của component scope (như prop và state) nếu thay đổi theo các lần render và effect có sử dụng**. Nếu không, nếu không nó sẽ tham chiếu tới giá trị trước đó. Đọc thêm [làm việc với function](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) và [làm gì khi array thay đổi thường xuyên](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often). > ->If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the dependencies array always works. +>Nếu muốn chạy 1 effect và clean nó 1 lần duy nhất (lúc mount và unmount), bạn có thể truyền vào array rỗng (`[]`). Đồng nghĩa với việc bạn báo với React, effect này không phụ thuộc *bất kỳ* giá trị nào của prop hoặc state, do đó không bao giờ cần re-run. Nó không phải là một trường hợp được xử lý đặc biệt -- nó đúng với cách so sánh array hiện tại > ->If you pass an empty array (`[]`), the props and state inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem. +>Nếu truyền vào array rỗng (`[]`), prop và state bên trong effect sẽ luôn mang giá trị khởi tạo. Trong khi truyền vào `[]` nó gần giống với `componentDidMount` và `componentWillUnmount`, nó thường là [giải pháp](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) [tốt hơn](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) để tránh re-run effect quá thường xuyên. Tuy nhiên, đừng quên React sẽ chỉ chạy `useEffect` sau khi trình duyệt paint. > ->We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. +>Chúng tôi khuyến khích sử dụng [`đưa tất cả dependency`](https://github.com/facebook/react/issues/14920), sử dụng [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package để ràng buộc, và thông báo nếu khai báo dependency không hợp lệ. -## Next Steps {#next-steps} +## Bước tiếp theo {#next-steps} -Congratulations! This was a long page, but hopefully by the end most of your questions about effects were answered. You've learned both the State Hook and the Effect Hook, and there is a *lot* you can do with both of them combined. They cover most of the use cases for classes -- and where they don't, you might find the [additional Hooks](/docs/hooks-reference.html) helpful. +Xin chúc mừng! Trang này không hề ngắn, nhưng bạn đã đọc được đến đây. Hy vọng các thắc mắc của bạn về effect đã được phúc đáp. Bạn đã học được State Hook và Effect Hook, và có *rất* nhiều thứ bạn có thể làm khi sử dụng kết hợp chúng. Nó gần như giải quyết các vấn đề mà chỉ có class mới làm được -- còn nếu không bạn có thể tìm thấy [các Hook mở rộng](/docs/hooks-reference.html). + +Chúng ta đã trình bài động lực tạo ra Hook [ở đây](/docs/hooks-intro.html#motivation). Chúng ta cũng thấy được cách effect cleanup và tránh trùng lặp trong `componentDidUpdate` và `componentWillUnmount`, mang những đoạn code có liên quan lại gần nhau hơn, và giúp chúng ta tránh bug. Chúng ta cũng thấy được cách chúng ta tách effect theo mục đích, cái mà chúng ta không làm được với class. + +Đến đây, bạn có thể thắc mắc Hook làm việc như thế nào. Làm cách nào `useState` lấy được đúng giá trị giữa các lần render khác nhau? Làm cách nào React "match" được effect trước và lần đang update? **Ở trang tiếp theo bạn sẽ học được [Quy luật của Hook](/docs/hooks-rules.html) -- mấu chốt làm việc của Hook.** -We're also starting to see how Hooks solve problems outlined in [Motivation](/docs/hooks-intro.html#motivation). We've seen how effect cleanup avoids duplication in `componentDidUpdate` and `componentWillUnmount`, brings related code closer together, and helps us avoid bugs. We've also seen how we can separate effects by their purpose, which is something we couldn't do in classes at all. -At this point you might be questioning how Hooks work. How can React know which `useState` call corresponds to which state variable between re-renders? How does React "match up" previous and next effects on every update? **On the next page we will learn about the [Rules of Hooks](/docs/hooks-rules.html) -- they're essential to making Hooks work.** From da04272671adb4a3e1c108267f611ad5f845c7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C6=B0u=20B=C3=ACnh=20An?= Date: Wed, 3 Jul 2019 17:25:14 +0700 Subject: [PATCH 2/5] update translation for hook intro --- content/docs/hooks-intro.md | 77 +++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/content/docs/hooks-intro.md b/content/docs/hooks-intro.md index 1fde6eb22..35ef49117 100644 --- a/content/docs/hooks-intro.md +++ b/content/docs/hooks-intro.md @@ -1,11 +1,11 @@ --- id: hooks-intro -title: Giới thiệu về Hooks +title: Giới thiệu về Hook permalink: docs/hooks-intro.html next: hooks-overview.html --- -*Hooks* mới được thêm ở phiên bản React 16.8. Cho phép bạn sử dụng state và các chức năng khác của React mà không cần tạo class. +*Hooks* mới được thêm ở phiên bản React 16.8. Cho phép bạn sử dụng state và các chức năng khác của React class component. ```js{4,5} import React, { useState } from 'react'; @@ -25,86 +25,87 @@ function Example() { } ``` -Tính năng mới `useState` này là "Hook" đầu tiên chúng ta học, nhưng ví dụ này chỉ để giới thiệu. Đừng lo nếu nó chưa dễ hình dung! +Tính năng mới `useState` này là "Hook" đầu tiên chúng ta học, ví dụ này chỉ để giới thiệu. Đừng lo nếu nó chưa dễ hình dung! -**Bạn có thể bắt đầu học Hooks [ở trang tiếp theo](/docs/hooks-overview.html).** Tại trang này, chúng tôi tiếp tục giải thích tại sao thêm Hooks vào React và cách chúng giúp bạn viết ứng dụng tuyệt vời hơn. +**Bạn có thể bắt đầu học Hook [ở trang tiếp theo](/docs/hooks-overview.html).** Ở đây, giải thích tại sao chúng tôi thêm Hook vào React và nó giúp bạn giải quyết những vấn đề gì. >Chú ý > ->React 16.8.0 là phiên bản đầu tiên hỗ trợ Hook. Khi nâng cấp, đừng quên cập nhật tất cả các gói, bao gồm cả React DOM. React Native sẽ hỗ trợ Hooks trong phiên bản ổn định tiếp theo. +>React 16.8.0 là phiên bản đầu tiên hỗ trợ Hook. Khi nâng cấp, đừng quên cập nhật tất cả các package bao gồm React DOM. React Native sẽ hỗ trợ Hook trong phiên bản ổn định tiếp theo. ## Video Giới Thiệu {#video-introduction} -Tại React Conf 2018, Sophie Alpert và Dan Abramov đã giới thiệu Hooks, tiếp theo Ryan Florence trình bày cách để tái cấu trúc một ứng dụng để sử dụng chúng. Xem video tại đây: +Tại React Conf 2018, Sophie Alpert và Dan Abramov đã giới thiệu Hook, tiếp theo Ryan Florence trình bày cách để tái cấu trúc một ứng dụng để sử dụng chúng. Xem video tại đây:
-## Không Có Thay Đổi Phá Vỡ {#no-breaking-changes} +## Thay đổi này không ảnh hưởng đến phiên bản trước{#no-breaking-changes} -Trước khi chúng ta tiếp tục, chú ý rằng Hooks: +Trước khi chúng ta tiếp tục, lưu ý rằng Hook: -* **Hoàn toàn opt-in.** Bạn có thể dùng Hooks trong một vài thành phần mà không phải viết lại bất cứ đoạn code hiện tại nào. Bạn không buộc phải học hoặc sử dụng Hooks bây giờ nếu bạn không muốn. -* **100% tương thích phiên bản cũ.** Hooks không chứa bất kì thay đổi phá vỡ nào. -* **Đã ra mắt.** Hooks đã sẵn sàng với phiên bản v16.8.0. +* **Hoàn toàn không bắt buộc.** Bạn có thể dùng Hook trong một vài component mà không phải viết lại bất cứ đoạn code hiện tại nào. Bạn không buộc phải học hoặc sử dụng Hook bây giờ nếu bạn không muốn. +* **100% tương thích phiên bản cũ.** Hook không chứa bất kỳ thay đổi nào ảnh hưởng phiên bản trước đó. +* **Đã chính thức được công bố.** Hook đã sẵn sàng với phiên bản v16.8.0. -**Không có kế hoạch xoá classes khỏi React.** Bạn có thể đọc thêm về chiến lược áp dụng dần dần cho Hook trong [phần dưới](#gradual-adoption-strategy) của trang này. +**Không có kế hoạch xóa class component khỏi React.** Bạn có thể đọc thêm về chiến lược áp dụng Hook dần dần trong [phần dưới](#gradual-adoption-strategy) của trang này. -**Hooks không thay thế kiến thức của bạn về các khái niệm của React.** Thay vì thế Hooks cung cấp các API trực tiếp tới các khái niệm React mà bạn đã biết: props, state, context, refs, và vòng đời. Chúng tôi sẽ chỉ ra sau, Hooks cũng đưa ra 1 cách mới và mạnh mẽ để kết hợp chúng. +**Hooks không thay đổi kiến thức của bạn về các khái niệm của React.** Thay vì thế, Hook cung cấp các API trực tiếp tới các khái niệm React mà bạn đã biết: prop, state, context, refs, và lifecycle. Chúng tôi sẽ chỉ ra sau, Hook cũng đưa ra 1 cách mới, mạnh mẽ hơn để kết hợp với chúng. -**Nếu bạn chỉ muốn tìm hiểu Hook, bạn có thể [xem luôn trang tiếp theo!](/docs/hooks-overview.html)** Bạn cũng có thể tiếp tục đọc để biết thêm tại sao chúng tôi thêm Hooks, và cách chúng tôi bắt đầu sử dụng mà không phải viết lại các ứng dụng của chúng tôi. +**Nếu bạn chỉ muốn tìm hiểu Hook, bạn có thể [xem luôn trang tiếp theo!](/docs/hooks-overview.html)** Bạn cũng có thể tiếp tục đọc để biết thêm tại sao chúng tôi thêm Hook, và cách chúng tôi bắt đầu sử dụng mà không phải viết lại các ứng dụng. -## Nguồn cảm hứng {#motivation} +## Động lực {#motivation} -Hooks giải quyết rộng và nhiều các vấn đề có vẻ không liên quan trong React mà chúng tôi gặp phải trong hơn 5 năm qua với việc viết và phát triển 10 nghìn thành phần giao diện. Kể cả bạn đang học React, sử dụng nó hàng ngày hoặc ngay cả bạn thích 1 thư viện khác tương tự với component model, bạn có thể nhận ra một số vấn đề. +Hook giải quyết nhiều vấn đề có vẻ không liên quan trong React mà chúng tôi gặp phải trong hơn 5 năm qua với việc viết và phát triển 10 nghìn component giao diện. Kể cả bạn đang học React, sử dụng nó hàng ngày hoặc ngay cả bạn thích 1 thư viện khác tương tự với component model, bạn có thể nhận ra một số vấn đề. -### Khó để sử dụng lại logic có trạng thái giữa các components{#its-hard-to-reuse-stateful-logic-between-components} +### Khó để sử dụng lại logic giữa các component{#its-hard-to-reuse-stateful-logic-between-components} -React không đưa ra cách nào để "gắn" các thao thác sử dụng lại tới một component (ví dụ, kết nối với store). Nếu bạn đã làm việc với React một thời gian, bạn có thể thấy quen thuộc với patterns như [render props](/docs/render-props.html) và [higher-order components](/docs/higher-order-components.html) đã cố để xử lý vấn đề này. Nhưng các patterns đó yêu cầu bạn phải cấu trúc lại components của bạn khi sử dụng, có thể làm cho code dài dòng khó theo dõi. Nếu bạn xem cấu trúc của một ứng dụng React bằng React DevTools bạn sẽ thấy "wrapper hell" (lồng nhau nhiều lớp) của các components bọc bởi các lớp của providers, consumers, higher-order components, render props, và các abstractions khác. Trong khi chúng ta có thể [lọc chúng khỏi DevTools](https://github.com/facebook/react-devtools/pull/503), điều này chỉ ra một vấn đề sâu hơn nằm bên dưới: React cần một kiểu nguyên thuỷ tốt hơn để chia sẻ logic có trạng thái. +React không đưa ra cách nào để "gắn" các thao tác hay sử dụng lại tới một component (ví dụ, kết nối với store). Nếu đã làm việc với React một thời gian, có thể thấy quen thuộc với pattern như [render prop](/docs/render-props.html) và [higher-order component](/docs/higher-order-components.html) để xử lý vấn đề này. Nhưng các pattern đó yêu cầu bạn phải cấu trúc lại component khi sử dụng, có thể làm cho code dài dòng khó theo dõi. Nếu bạn xem cấu trúc của một ứng dụng React bằng React DevTools bạn sẽ thấy "wrapper hell" (lồng nhau nhiều lớp) của các component bọc bởi các lớp của provider, consumer, higher-order component, render prop, và các abstraction khác. Trong khi chúng ta có thể [lọc chúng khỏi DevTools](https://github.com/facebook/react-devtools/pull/503), điều này chỉ ra một vấn đề sâu hơn nằm bên dưới: React cần một kiểu nguyên thuỷ tốt hơn để chia sẻ logic. -Với Hooks, bạn có thể tách logic có trạng thái từ component, nó có thể test độc lập và sử dụng lại. **Hooks cho phép sử dụng lại logic có trạng thái mà không phải thay đổi cấu trúc component.** Điều này cho phép chia sẻ Hooks qua nhiều components hoặc với cộng đồng. +Với Hook, bạn có thể tách logic từ component, nó có thể test độc lập và sử dụng lại. **Hook cho phép sử dụng lại logic mà không phải thay đổi cấu trúc component.** Điều này cho phép chia sẻ Hook qua nhiều component hoặc với cộng đồng. -Chúng tôi sẽ thảo luận về điều này nhiều hơn tại [Xây dựng Hooks của bạn](/docs/hooks-custom.html). +Chúng tôi sẽ thảo luận về điều này nhiều hơn tại [Xây dựng Hook của tùy biến](/docs/hooks-custom.html). -### Components phức tạp trở nên khó hiểu {#complex-components-become-hard-to-understand} +### Component phức tạp trở nên khó hiểu {#complex-components-become-hard-to-understand} -Chúng ta thường phải làm những components mà bắt đầu đơn giản nhưng trở nên khó quản lý và bừa bộn các logic có trạng thái và side effects. Mỗi phương thức vòng đời chứa kết hợp những logic không liên quan. Ví dụ, components có thể thực hiện lấy dữ liệu trong `componentDidMount` và `componentDidUpdate`. Tuy nhiên, cùng phương thức `componentDidMount` có thể chứa vài logic không liên quan để cài đặt event listeners, và dọn dẹp trong `componentWillUnmount`. Những đoạn code liên quan và hỗ trợ lẫn nhau bị chia ra, và đoạn code không liên quan lại nằm trong cùng một phương thức. Điều này dễ dàng gây ra bugs và không nhất quán. +Chúng ta thường phải làm những component đầu tiên đơn giản, nhưng trở nên khó quản lý và bừa bộn các logic và side effect. Mỗi phương thức lifecycle kết hợp những logic không liên quan. Ví dụ, component có thể thực hiện lấy dữ liệu trong `componentDidMount` và `componentDidUpdate`. Tuy nhiên, cùng phương thức `componentDidMount` có thể chứa vài logic không liên quan để cài đặt event listener, và dọn dẹp trong `componentWillUnmount`. Những đoạn code liên quan và hỗ trợ lẫn nhau bị chia ra, và đoạn code không liên quan lại nằm trong cùng một phương thức. Điều này dễ dàng gây ra bug và không nhất quán. -Trong nhiều trường hợp không thể chia nhỏ các components bởi vì logic có trạng thái dùng ở tất cả các chỗ. Khó để test. Đây là một trong những nguyên nhân nhiều người chọn kết hợp React với một thư viện quản lý trạng thái khác. Tuy nhiên nó thường bị quá nhiều trìu tượng và yêu cầu phải chuyển qua nhiều files khác nhau và khó sử dụng lại các components. +Trong nhiều trường hợp không thể chia nhỏ các component bởi vì logic dùng ở tất cả các chỗ. Khó để test. Đây là một trong những nguyên nhân nhiều người chọn kết hợp React với một thư viện quản lý state khác. Tuy nhiên nó thường quá trừu tượng và yêu cầu phải chuyển qua nhiều file khác nhau và khó sử dụng lại các component. -Để giải quyết vấn đề này, **Hooks cho phép bạn chia một component thành các hàm nhỏ hơn dựa trên các phần liên quan (chẳng hạn như cài đặt subscription hoặc lấy dữ liệu)**, hơn là buộc phải chia theo các phương thức vòng đời. Bạn cũng có thể quản lý trạng thái của component với reducer để dễ dự đoán hơn. +Để giải quyết vấn đề này, **Hook cho phép bạn chia một component thành các hàm nhỏ hơn dựa trên các phần liên quan (chẳng hạn như cài đặt subscription hoặc lấy dữ liệu)**, hơn là buộc phải chia theo các phương thức lifecycle. Bạn cũng có thể quản lý trạng thái của component với reducer để dễ dự đoán hơn. -Chúng tôi sẽ thảo luận thêm tại [Sử dụng Hook hiệu quả](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns). +Chúng tôi sẽ thảo luận thêm tại [Sử dụng nhiều effect Hook độc lập](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns). -### Classes khiến cả con người và máy thấy bối rối {#classes-confuse-both-people-and-machines} +### Class khiến cả con người và máy thấy bối rối {#classes-confuse-both-people-and-machines} -Không chỉ làm cho việc sử dụng lại và tổ chức code khó hơn, chúng tôi thấy rằng classes là rào cản lớn để học React. Bạn phải hiểu cách `this` hoạt động trong Javascript, cái mà rất khác về cách hoạt động trong đa số các ngôn ngữ khác. Bạn phải nhớ bind các event handlers. Nếu không sử dụng [cú pháp đề xuất](https://babeljs.io/docs/en/babel-plugin-transform-class-properties/), code sẽ rất dài dòng. Mọi người có thể hiểu props, state, và luồng dữ liệu từ trên xuống tốt nhưng vẫn vật lộn với classes. Sự khác biết giữa hàm và class components trong React và khi nào sử dụng chúng dẫn đến sự bất đồng kể cả những người phát triển React có kinh nghiệm. +Không chỉ làm cho việc sử dụng lại và tổ chức code khó hơn, chúng tôi thấy rằng class là rào cản lớn để học React. Bạn phải hiểu cách `this` hoạt động trong Javascript, cái mà rất khác về cách hoạt động trong đa số các ngôn ngữ khác. Bạn phải nhớ bind các event handler. Nếu không sử dụng [cú pháp đề xuất](https://babeljs.io/docs/en/babel-plugin-transform-class-properties/), code sẽ rất dài dòng. Mọi người có thể hiểu prop, state, và luồng dữ liệu từ trên xuống tốt nhưng vẫn vật lộn với class. Sự khác biệt giữa hàm và class component trong React và khi nào sử dụng chúng dẫn đến sự bất đồng kể cả những người phát triển React có kinh nghiệm. -Hơn nữa, React đã ra mắt được khoảng 5 năm, và chúng tôi muốn đảm bảo nó vẫn liên quan trong 5 năm tới. [Svelte](https://svelte.dev/), [Angular](https://angular.io/), [Glimmer](https://glimmerjs.com/), và nhiều chỗ khác chỉ ra, [ahead-of-time compilation](https://en.wikipedia.org/wiki/Ahead-of-time_compilation) của các components có rất nhiều tiềm năng tương lai. Đặc biệt nếu nó không giới hạn các mẫu. Gần đây chúng tôi đã thử nghiệm [component folding](https://github.com/facebook/react/issues/7323) sử dụng [Prepack](https://prepack.io/), và chúng tôi đã thấy nhiều kết quả hứa hẹn. Chúng tôi thấy rằng class components có thể khuyến khích các patterns không chủ ý nhưng làm cho các tối ưu chậm hơn. Classes cũng xuất nhiện nhiều vấn đề cho các công cụ hôm nay. Ví dụ class không giảm dung lượng tốt, và chúng làm cho hot reloading flaky và không tin cậy. Chúng tôi muốn giới thiệu một API mà vẫn tối ưu được. +Hơn nữa, React đã ra mắt được khoảng 5 năm, và chúng tôi muốn đảm bảo nó vẫn mạnh mẽ trong 5 năm tới. [Svelte](https://svelte.dev/), [Angular](https://angular.io/), [Glimmer](https://glimmerjs.com/), và nhiều chỗ khác chỉ ra, [ahead-of-time compilation](https://en.wikipedia.org/wiki/Ahead-of-time_compilation) của các components có rất nhiều tiềm năng tương lai. Đặc biệt nếu nó không giới hạn các mẫu. Gần đây chúng tôi đã thử nghiệm [component folding](https://github.com/facebook/react/issues/7323) sử dụng [Prepack](https://prepack.io/), và chúng tôi đã thấy nhiều kết quả hứa hẹn. Chúng tôi thấy rằng class component có thể khuyến khích các pattern không chủ ý nhưng làm cho việc tối ưu chậm hơn. Class cũng xuất hiện nhiều vấn đề hôm nay. Ví dụ class không giảm dung lượng tốt, và chúng làm cho hot reloading flaky và không tin cậy. Chúng tôi muốn giới thiệu một API mà vẫn tối ưu được. -Để xử lý các vấn đề, **Hooks cho phép bạn sử dụng nhiều tính năng của React mà không cần classes.** Về mặt khái niệm, React components luôn luôn gần như các hàm. Hooks áp dụng functions, nhưng không phải hi sinh tinh thần thực hành của React. Hooks cung cấp truy cập đến escape hatches nguyên thuỷ và không yêu cầu bạn phải học các kĩ thuật functional hoặc reactive programming. +Để xử lý các vấn đề, **Hook cho phép bạn sử dụng nhiều tính năng của React mà không cần class.** Về mặt khái niệm, React component luôn luôn gần như các hàm. Hook áp dụng function, nhưng không phải hi sinh tinh thần của React. Hook cung cấp truy cập đến escape hatches nguyên thuỷ và không yêu cầu bạn phải học các kĩ thuật functional hoặc reactive programming. >Ví dụ > ->[Cái nhìn đầu tiên về Hooks](/docs/hooks-overview.html) là một nơi tốt để bắt đầu học Hooks. +>[Cái nhìn đầu tiên về Hooks](/docs/hooks-overview.html) là một nơi tốt để bắt đầu học Hook. ## Chiến lược áp dụng dần dần {#gradual-adoption-strategy} ->**TLDR: Không có kế hoạch xoá classes khỏi React.** +>**TLDR: Không có kế hoạch xóa class khỏi React.** -Chúng tôi biết lập tình viên React tập trung vào phát triển sản phẩm và không có thời gian để xem tất cả các API mới đang được ra mắt. Hooks rất mới và có thể tốt hơn để chờ cho nhiều ví dụ và hướng dẫn trước khi cân nhắc học hoặc áp dụng chúng. +Chúng tôi biết lập trình viên React tập trung vào phát triển sản phẩm và không có thời gian để xem tất cả các API mới đang được ra mắt. Hook rất mới và tốt hơn nên chờ khi có nhiều ví dụ và hướng dẫn trước khi cân nhắc học hoặc áp dụng chúng. -Chúng tôi cũng hiểu rằng cản trở cho việc thêm một điều nguyên thuỷ mới vào React là rất cao. Cho những người đọc tò mò, chúng tôi đã chuẩn bị một [RFC chi tiết](https://github.com/reactjs/rfcs/pull/68) cho nguồn cảm hứng với nhiều chi tiết hơn, và cung cấp thêm quan điểm về quyết định thiết kế và nghệ thuật nguyên thuỷ. +Chúng tôi cũng hiểu rằng việc thêm một điều mới hoàn toàn vào React là rất khó khăn. Cho những người đọc tò mò, chúng tôi đã chuẩn bị một [RFC chi tiết](https://github.com/reactjs/rfcs/pull/68) giải thích động lực chi tiết hơn, và cung cấp thêm quan điểm về quyết định thiết kế. +**Chủ yếu, Hook hoạt động bên cạnh code hiện tại nên bạn có thể áp dụng dần dần.** Không quá mất thời gian để chuyển sang dùng Hook. Chúng tôi thiết nghĩ hạn chế việc "viết lại toàn bộ" bằng Hook, đặc biệt cho những class component phức tạp. Nó cần một chút thay đổi tư duy để bắt đầu "suy nghĩ về Hook". Theo kinh nghiệm của chúng tôi thì cách tốt nhất để sử dụng Hook là ở trong các component mới và không quan trọng, và đảm bảo mọi người trong nhóm của bạn cảm thấy thoải mái với chúng. Sau khi bạn thử Hook, hãy thoải mái [gửi phản hồi](https://github.com/facebook/react/issues/new), kể cả tích cực hay tiêu cực. -**Chủ yếu, Hooks hoạt động bên cạnh code hiện tại nên bạn có thể áp dụng dần dần.** Không quá mất thời gian để chuyển sang dùng Hooks. Chúng tôi gợi ý hạn chế bất kì việc "viết lại lớn" nào, đặc biệt cho những class component phức tạp. Nó cần một chút thay đổi tư duy để bắt đầu "suy nghĩ về Hooks". Theo kinh nghiệm của chúng tôi thì cách tốt nhất để sử dụng Hooks là ở trong các components mới và không quan trọng, và đảm bảo mọi người trong nhóm của bạn cảm thấy thoải mái với chúng. Sau khi bạn thử Hooks, hãy thoải mái [gửi phản hồi](https://github.com/facebook/react/issues/new), kể cả tích cực hay tiêu cực. - -Chúng tôi dự định cho Hooks bao hàm tất cả các trường hợp dùng classes, nhưng **chúng tôi sẽ tiếp tục hỗ trợ class components cho tương lai thấy trước.** Tại Facebook, chúng tôi có hàng mười nghìn components viết dưới dạng classes, và chúng tôi tuyệt đối không có kế hoạch viết lại chúng. Thay vì thế, chúng tôi bắt đầu sử dụng Hooks cho code mới bên cạnh với classes. +Chúng tôi dự định cho Hook bao gồm tất cả các trường hợp dùng class, nhưng **chúng tôi sẽ tiếp tục hỗ trợ class component cho tương lai.** Tại Facebook, chúng tôi có hàng nghìn component viết dưới dạng class, và chúng tôi tuyệt đối không có kế hoạch viết lại chúng. Thay vì thế, chúng tôi bắt đầu sử dụng Hook cho code mới bên cạnh với class. ## Các câu hỏi thường gặp {#frequently-asked-questions} -Chúng tôi đã chuẩn bị [câu hỏi thường gặp về Hooks](/docs/hooks-faq.html) để trả lời những câu hỏi phổ biến nhất về Hooks. +Chúng tôi đã chuẩn bị [câu hỏi thường gặp về Hook](/docs/hooks-faq.html) để trả lời những câu hỏi phổ biến nhất về Hook. ## Bước tiếp theo {#next-steps} -Cuối trang này, bạn phần nào có được ý tưởng mà Hooks đang giải quyết, nhưng nhiều chi tiết chắc chắn là chưa rõ ràng. Đừng lo! **Bắt đầu [trang tiếp theo](/docs/hooks-overview.html) để bắt đầu học Hooks qua những ví dụ** +Cuối trang này, bạn phần nào có được ý tưởng mà Hook đang giải quyết, nhưng nhiều chi tiết chắc chắn là chưa rõ ràng. Đừng lo! **Bắt đầu [trang tiếp theo](/docs/hooks-overview.html) để bắt đầu học Hook qua những ví dụ** + + From 4d73aaf8f7cf59174ce6342248e0154de8758443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C6=B0u=20B=C3=ACnh=20An?= Date: Thu, 4 Jul 2019 22:38:15 +0700 Subject: [PATCH 3/5] Translate to Vietnamese --- content/docs/hooks-rules.md | 93 ++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/content/docs/hooks-rules.md b/content/docs/hooks-rules.md index 625d1e4d5..1cfaaa059 100644 --- a/content/docs/hooks-rules.md +++ b/content/docs/hooks-rules.md @@ -1,38 +1,38 @@ --- id: hooks-rules -title: Rules of Hooks +title: Nguyên tắc sử dụng Hook permalink: docs/hooks-rules.html next: hooks-custom.html prev: hooks-effect.html --- -*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. +*Hook* là một tính năng mới từ React 16.8. Nó cho phép sử dụng state và các tính năng khác của React mà không cần viết dạng class -Hooks are JavaScript functions, but you need to follow two rules when using them. We provide a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce these rules automatically: +Hook là các function JavaScript, có những quy luật bạn cần phải tuân theo khi sử dụng. Chúng tôi có [một plugin linter](https://www.npmjs.com/package/eslint-plugin-react-hooks) để đảm bảo các luật này luôn luôn được áp dụng đúng: -### Only Call Hooks at the Top Level {#only-call-hooks-at-the-top-level} +### Chỉ gọi Hook ở trên cùng {#only-call-hooks-at-the-top-level} -**Don't call Hooks inside loops, conditions, or nested functions.** Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That's what allows React to correctly preserve the state of Hooks between multiple `useState` and `useEffect` calls. (If you're curious, we'll explain this in depth [below](#explanation).) +**Không gọi hook bên trong loop, câu điều kiện, hay các function lồng với nhau.** Thay vì đó, luôn sử dụng Hook ở phần trên cùng của function. Với cách này, bạn đảm bảo các Hook được gọi theo đúng thứ tự trong các lần render. Nó cho phép React có được đúng state giữa nhiều lần gọi `useState` và `useEffect`. (Nếu bạn có thắc mắc, chúng tôi sẽ giải thích trong phần giải thích cụ thể hơn [bên dưới](#explanation).) -### Only Call Hooks from React Functions {#only-call-hooks-from-react-functions} +### Chỉ gọi Hook từ React Function {#only-call-hooks-from-react-functions} -**Don't call Hooks from regular JavaScript functions.** Instead, you can: +**Không gọi Hook từ mà function JavaScript.** Thay vì đó, bạn có thể: -* ✅ Call Hooks from React function components. -* ✅ Call Hooks from custom Hooks (we'll learn about them [on the next page](/docs/hooks-custom.html)). +* ✅ Gọi Hook từ React function components. +* ✅ Gọi Hook từ custom Hook (Chúng ta sẽ học [ở trang sau](/docs/hooks-custom.html)). -By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code. +Khi tuân theo quy luật này, chúng ta đảm bảo tất cả logic trong 1 component rõ ràng nhất. ## ESLint Plugin {#eslint-plugin} -We released an ESLint plugin called [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces these two rules. You can add this plugin to your project if you'd like to try it: +Chúng tôi có cung cấp plugin ESLint tên là [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) đảm bảo 2 luật này luôn được áp dụng. Nếu thích bạn có thể thêm vào project: ```bash npm install eslint-plugin-react-hooks --save-dev ``` ```js -// Your ESLint configuration +// cài đặt ESLint { "plugins": [ // ... @@ -40,34 +40,34 @@ npm install eslint-plugin-react-hooks --save-dev ], "rules": { // ... - "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks - "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies + "react-hooks/rules-of-hooks": "error", // Kiểm tra rule của Hook + "react-hooks/exhaustive-deps": "warn" // Kiểm tra effect dependency } } ``` -In the future, we intend to include this plugin by default into Create React App and similar toolkits. +Trong tương lai, chúng tôi có định sẽ gộp luôn 2 plugin này vào trong Create React App và các bộ công cụ tương tự -**You can skip to the next page explaining how to write [your own Hooks](/docs/hooks-custom.html) now.** On this page, we'll continue by explaining the reasoning behind these rules. +**Bạn có thể bỏ qua và đọc tiếp trang chỉ dẫn [tạo custom Hook](/docs/hooks-custom.html) bây giờ.** Ở đây, chúng ta sẽ tiếp tục giải thích lý do đằng sau những quy luật này. -## Explanation {#explanation} +## Giải thích {#explanation} -As we [learned earlier](/docs/hooks-state.html#tip-using-multiple-state-variables), we can use multiple State or Effect Hooks in a single component: +Như chúng ta [đã học trước đây](/docs/hooks-state.html#tip-using-multiple-state-variables), chúng ta có thể sử dụng nhiều state hoặc nhiều effect trên một component ```js function Form() { - // 1. Use the name state variable + // 1. Sử dụng state tên name const [name, setName] = useState('Mary'); - // 2. Use an effect for persisting the form + // 2. Sử dụng một effect lưu giá trị trên form useEffect(function persistForm() { localStorage.setItem('formData', name); }); - // 3. Use the surname state variable + // 3. Sử dụng state tên surname const [surname, setSurname] = useState('Poppins'); - // 4. Use an effect for updating the title + // 4. Sử dụng 1 effect cập nhập title useEffect(function updateTitle() { document.title = name + ' ' + surname; }); @@ -76,32 +76,31 @@ function Form() { } ``` -So how does React know which state corresponds to which `useState` call? The answer is that **React relies on the order in which Hooks are called**. Our example works because the order of the Hook calls is the same on every render: +Vậy làm sao React biết được state nào ứng với lúc gọi `useState` ? Câu trả lời là **React dựa trên thứ tự Hook được gọi**. Trong ví dụ trên, vì thứ tự Hook được gọi đúng theo lúc khai báo trong khi render: ```js // ------------ -// First render +// Lần đầu render // ------------ -useState('Mary') // 1. Initialize the name state variable with 'Mary' -useEffect(persistForm) // 2. Add an effect for persisting the form -useState('Poppins') // 3. Initialize the surname state variable with 'Poppins' -useEffect(updateTitle) // 4. Add an effect for updating the title +useState('Mary') // 1. Khởi tạo biết name với giá trị 'Mary' +useEffect(persistForm) // 2. Thêm một effect +useState('Poppins') // 3. KHởi tạo biến surname với giá trị 'Poppins' +useEffect(updateTitle) // 4. Thêm một effect cập nhập title // ------------- -// Second render +// Lần gọi render thứ 2 // ------------- -useState('Mary') // 1. Read the name state variable (argument is ignored) -useEffect(persistForm) // 2. Replace the effect for persisting the form -useState('Poppins') // 3. Read the surname state variable (argument is ignored) -useEffect(updateTitle) // 4. Replace the effect for updating the title +useState('Mary') // 1. Đọc giá trị biến name +useEffect(persistForm) // 2. Thay thế effect cũ +useState('Poppins') // 3. Đọc giá trị biến surname +useEffect(updateTitle) // 4. Thay thế effect cập nhập title // ... ``` -As long as the order of the Hook calls is the same between renders, React can associate some local state with each of them. But what happens if we put a Hook call (for example, the `persistForm` effect) inside a condition? - +Miễn là thứ tự của Hook gọi đúng theo thứ tự giữa các lần render, React có thể liên kết local state với nhau. Chuyện gì sẽ xảy ra nếu chúng ta đặt câu gọi Hook (ví dụ như `persistForm` bên trong trong câu điều kiện? ```js - // 🔴 We're breaking the first rule by using a Hook in a condition + // 🔴 Chúng ta vi phạm nguyên tắc không đặt trong câu điều kiện if (name !== '') { useEffect(function persistForm() { localStorage.setItem('formData', name); @@ -109,30 +108,30 @@ As long as the order of the Hook calls is the same between renders, React can as } ``` -The `name !== ''` condition is `true` on the first render, so we run this Hook. However, on the next render the user might clear the form, making the condition `false`. Now that we skip this Hook during rendering, the order of the Hook calls becomes different: +Trong lần đầu render, mệnh đề điều kiện `name !== ''` trả về `true`, Hook sẽ được gọi. Tuy nhiên, trong lần gọi tiếp theo, user có thể xóa giá trị trong form, việc này làm cho mệnh đề điều kiện trả về `false`, chúng ta bỏ qua câu gọi effect, thứ tự gọi Hook cũng thay đổi theo: ```js -useState('Mary') // 1. Read the name state variable (argument is ignored) -// useEffect(persistForm) // 🔴 This Hook was skipped! -useState('Poppins') // 🔴 2 (but was 3). Fail to read the surname state variable -useEffect(updateTitle) // 🔴 3 (but was 4). Fail to replace the effect +useState('Mary') // 1. Đọc giá trị name +// useEffect(persistForm) // 🔴 Hook bị bỏ qua! +useState('Poppins') // 🔴 2 (thật ra là 3). Không đọc được giá trị surname +useEffect(updateTitle) // 🔴 3 (thật ra là 4). Không thể thay thế effect ``` -React wouldn't know what to return for the second `useState` Hook call. React expected that the second Hook call in this component corresponds to the `persistForm` effect, just like during the previous render, but it doesn't anymore. From that point, every next Hook call after the one we skipped would also shift by one, leading to bugs. +React không biết được trả về gì cho `useState` ở lần 2. React tưởng là Hook thứ 2 trong component tương ứng với effect `persistForm`, cũng giống như lần render trước, tuy nhiên không còn đúng nữa. Kể từ lúc đó, tất cả những lần gọi Hook sau đều bỏ qua một bước, dẫn đến bug. -**This is why Hooks must be called on the top level of our components.** If we want to run an effect conditionally, we can put that condition *inside* our Hook: +**Đó là lý do tại sao phải gọi Hook ở trên cùng của component**. Nếu chúng ta muốn chạy effect theo điều kiện, chúng ta có thể đặt điều kiện *bên trong* Hook: ```js useEffect(function persistForm() { - // 👍 We're not breaking the first rule anymore + // 👍 Không phá vỡ nguyên tắc nữa if (name !== '') { localStorage.setItem('formData', name); } }); ``` -**Note that you don't need to worry about this problem if you use the [provided lint rule](https://www.npmjs.com/package/eslint-plugin-react-hooks).** But now you also know *why* Hooks work this way, and which issues the rule is preventing. +**Lưu ý, bạn không cần lo lắng về vấn đề này nếu dùng [ lint](https://www.npmjs.com/package/eslint-plugin-react-hooks).** Giờ bạn cũng hiểu được *tại sao* Hook làm việc như vậy, và tại sao chúng ta lại có những nguyên tắc này. -## Next Steps {#next-steps} +## Tiếp theo {#next-steps} -Finally, we're ready to learn about [writing your own Hooks](/docs/hooks-custom.html)! Custom Hooks let you combine Hooks provided by React into your own abstractions, and reuse common stateful logic between different components. +Cuối cùng thì chúng ta cũng đã sẵn sàng học [cách viết custom Hooks](/docs/hooks-custom.html)! Custom Hook cho phép chúng ta kết hợp các Hook được cung cấp bởi React với những gì bạn muốn, tái sử dụng những logic giữa các component. From 9cf0ed54ee43170653c7b5a5851bc246eb026c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C6=B0u=20B=C3=ACnh=20An?= Date: Fri, 5 Jul 2019 11:24:21 +0700 Subject: [PATCH 4/5] Update hooks-effect.md --- content/docs/hooks-effect.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/docs/hooks-effect.md b/content/docs/hooks-effect.md index 87753ad75..5f2b5921c 100644 --- a/content/docs/hooks-effect.md +++ b/content/docs/hooks-effect.md @@ -35,9 +35,9 @@ function Example() { Đoạn snippet này dựa trên [ví dụ về counter ở trang trước](/docs/hooks-state.html), chúng ta có thêm tính năng mới: đặt giá trị document title tương ứng với số lần click. -Fetching data, thiết lập các subscription, và tự ý thay đổi DOM trong React component, những hành động như vậy được là "side effect" (hoặc "effect"). +Việc fetching data, thiết lập các subscription, và việc thay đổi DOM trong React component, những hành động như vậy được gọi là "side effect" (hoặc "effect). Bạn có thể đã sử dụng những "side effect" này trong những component của bạn trước đây. ->Tip +>Mẹo nhỏ > >Nếu bạn quen với các phương thức lifecycle của React class, bạn có thể hình dung `useEffect` Hook như sự kết hợp của `componentDidMount`, `componentDidUpdate`, và `componentWillUnmount`. From 3b09d87995c6cf25b87125f2c242c5c9ecf62e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C6=B0u=20B=C3=ACnh=20An?= Date: Fri, 5 Jul 2019 11:25:37 +0700 Subject: [PATCH 5/5] Update hooks-effect.md --- content/docs/hooks-effect.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/docs/hooks-effect.md b/content/docs/hooks-effect.md index 5f2b5921c..f71bcd67b 100644 --- a/content/docs/hooks-effect.md +++ b/content/docs/hooks-effect.md @@ -137,7 +137,7 @@ Chúng ta khai báo state `count`, và sau đó nói với React chúng ta cần Lập trình viên JavaScript có kinh nghiệm sẽ để ý thấy function truyền vào cho `useEffect` sẽ khác nhau cho tất cả các lần render. Đây là điều cố ý. Thật ra, nó sẽ cho chúng ta đọc giá trị `count` bên trong effect mà không cần lo lắng về việc lấy state. Mỗi lần chúng ta re-render, chúng ta gọi một effect **khác**, thay thế cái trước đó. Bằng cách này, nó làm cho effect như một phần của việc render -- mỗi effect "thuộc vào" một render cụ thể. Chúng ta sẽ hiểu tại sao cách này lại hiệu quả [ở phần sau của bài này](#explanation-why-effects-run-on-each-update). ->Tip +>Mẹo nhỏ > >Không giống `componentDidMount` hoặc `componentDidUpdate`, effect chạy với `useEffect` không block trình duyệt cập nhập màn hình. Các effect chủ yếu không cần xảy ra tuần tự. Trong vài tình huống không mấy phổ biến (ví dụ như đo layout), chúng ta có [`useLayoutEffect`](/docs/hooks-reference.html#uselayouteffect) Hook với API tính năng tương tự như `useEffect`. @@ -264,11 +264,11 @@ Effect Hook được sử dụng trong cả 2 trường hợp. ------------- -## Tip sử dụng Effect {#tips-for-using-effects} +## Mẹo nhỏ sử dụng Effect {#tips-for-using-effects} Chúng ta sẽ cùng đi sâu một số khía cạnh của `useEffect` mà các lập trình viên React có kinh nghiệm sẽ thắc mắc. Không cần quá cưỡng ép bản thân, bạn có thể dừng ở đây, và quay lại để tìm hiểu Effect Hook bất cứ lúc nào. -### Tip: Sử dụng nhiều Effect tách biệt{#tip-use-multiple-effects-to-separate-concerns} +### Mẹo nhỏ: Sử dụng nhiều Effect tách biệt{#tip-use-multiple-effects-to-separate-concerns} Một trong những vấn đề đã liệt kê ở [động lực](/docs/hooks-intro.html#complex-components-become-hard-to-understand) tạo ra Hooks là các phương thức lifecycle của class thường chứa những logic không liên quan với nhau, còn những logic đáng lý phải nằm gần nhau lại nằm ở các phương thức khác nhau. Đây là component kết hợp counter và friend status từ ví dụ ở trên @@ -428,7 +428,7 @@ ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // Clean effect l Đặc tính này đảm bảo thống nhất và ngăn bug thường xuất hiện do không cập nhập login với class component -### Tip: Tối ưu Performance bằng cách bỏ qua Effect {#tip-optimizing-performance-by-skipping-effects} +### Mẹo nhỏ: Tối ưu Performance bằng cách bỏ qua Effect {#tip-optimizing-performance-by-skipping-effects} Trong một số trường hợp, clean và apply effect sau khi render có thể dẫn đến ảnh hưởng performance. Trong class component, chúng ta giải quyết bằng viết một hàm so sánh giữa `prevProps` hoặc `prevState` bên trong `componentDidUpdate`: