diff --git a/src/content/learn/sharing-state-between-components.md b/src/content/learn/sharing-state-between-components.md index 52eaf28f..634bb02d 100644 --- a/src/content/learn/sharing-state-between-components.md +++ b/src/content/learn/sharing-state-between-components.md @@ -1,31 +1,31 @@ --- -title: Sharing State Between Components +title: Chia Sẻ State Giữa Các Component --- -Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as *lifting state up,* and it's one of the most common things you will do writing React code. +Đôi khi, bạn muốn state của hai component luôn thay đổi cùng nhau. Để làm được điều này, hãy loại bỏ state khỏi cả hai component, di chuyển nó lên parent gần nhất chung của chúng, và sau đó truyền xuống cho chúng thông qua props. Điều này được gọi là *lifting state up*, và đây là một trong những việc phổ biến nhất mà bạn sẽ làm khi viết code React. -- How to share state between components by lifting it up -- What are controlled and uncontrolled components +- Cách chia sẻ state giữa các component bằng cách lifting nó lên +- Controlled và uncontrolled component là gì -## Lifting state up by example {/*lifting-state-up-by-example*/} +## Lifting state up bằng ví dụ {/*lifting-state-up-by-example*/} -In this example, a parent `Accordion` component renders two separate `Panel`s: +Trong ví dụ này, component parent `Accordion` render hai `Panel` riêng biệt: * `Accordion` - `Panel` - `Panel` -Each `Panel` component has a boolean `isActive` state that determines whether its content is visible. +Mỗi component `Panel` có một state boolean `isActive` để xác định liệu nội dung của nó có hiển thị hay không. -Press the Show button for both panels: +Nhấn nút Show cho cả hai panel: @@ -73,59 +73,59 @@ h3, p { margin: 5px 0px; } -Notice how pressing one panel's button does not affect the other panel--they are independent. +Lưu ý cách nhấn nút của một panel không ảnh hưởng đến panel khác--chúng độc lập với nhau. -Initially, each `Panel`'s `isActive` state is `false`, so they both appear collapsed +Ban đầu, state `isActive` của mỗi `Panel` là `false`, vì vậy cả hai đều xuất hiện dạng thu gọn -Clicking either `Panel`'s button will only update that `Panel`'s `isActive` state alone +Nhấp vào nút của bất kỳ `Panel` nào sẽ chỉ cập nhật state `isActive` của `Panel` đó một mình -**But now let's say you want to change it so that only one panel is expanded at any given time.** With that design, expanding the second panel should collapse the first one. How would you do that? +**Nhưng giờ giả sử bạn muốn thay đổi để chỉ có một panel được mở rộng tại bất kỳ thời điểm nào.** Với thiết kế đó, việc mở rộng panel thứ hai sẽ thu gọn panel đầu tiên. Bạn sẽ làm thế nào? -To coordinate these two panels, you need to "lift their state up" to a parent component in three steps: +Để phối hợp hai panel này, bạn cần "lift state của chúng lên" component parent trong ba bước: -1. **Remove** state from the child components. -2. **Pass** hardcoded data from the common parent. -3. **Add** state to the common parent and pass it down together with the event handlers. +1. **Loại bỏ** state khỏi các component con. +2. **Truyền** dữ liệu cứng từ parent chung. +3. **Thêm** state vào parent chung và truyền nó xuống cùng với các event handler. -This will allow the `Accordion` component to coordinate both `Panel`s and only expand one at a time. +Điều này sẽ cho phép component `Accordion` phối hợp cả hai `Panel` và chỉ mở rộng một panel tại một thời điểm. -### Step 1: Remove state from the child components {/*step-1-remove-state-from-the-child-components*/} +### Bước 1: Loại bỏ state khỏi các component con {/*step-1-remove-state-from-the-child-components*/} -You will give control of the `Panel`'s `isActive` to its parent component. This means that the parent component will pass `isActive` to `Panel` as a prop instead. Start by **removing this line** from the `Panel` component: +Bạn sẽ giao quyền kiểm soát `isActive` của `Panel` cho component parent của nó. Điều này có nghĩa là component parent sẽ truyền `isActive` cho `Panel` như một prop thay vì. Bắt đầu bằng cách **loại bỏ dòng này** khỏi component `Panel`: ```js const [isActive, setIsActive] = useState(false); ``` -And instead, add `isActive` to the `Panel`'s list of props: +Và thay vào đó, thêm `isActive` vào danh sách props của `Panel`: ```js function Panel({ title, children, isActive }) { ``` -Now the `Panel`'s parent component can *control* `isActive` by [passing it down as a prop.](/learn/passing-props-to-a-component) Conversely, the `Panel` component now has *no control* over the value of `isActive`--it's now up to the parent component! +Bây giờ component parent của `Panel` có thể *kiểm soát* `isActive` bằng cách [truyền nó xuống như một prop.](/learn/passing-props-to-a-component) Ngược lại, component `Panel` bây giờ *không có quyền kiểm soát* giá trị của `isActive`--giờ đây việc này thuộc về component parent! -### Step 2: Pass hardcoded data from the common parent {/*step-2-pass-hardcoded-data-from-the-common-parent*/} +### Bước 2: Truyền dữ liệu cứng từ parent chung {/*step-2-pass-hardcoded-data-from-the-common-parent*/} -To lift state up, you must locate the closest common parent component of *both* of the child components that you want to coordinate: +Để lift state lên, bạn phải tìm component parent chung gần nhất của *cả hai* component con mà bạn muốn phối hợp: -* `Accordion` *(closest common parent)* +* `Accordion` *(parent chung gần nhất)* - `Panel` - `Panel` -In this example, it's the `Accordion` component. Since it's above both panels and can control their props, it will become the "source of truth" for which panel is currently active. Make the `Accordion` component pass a hardcoded value of `isActive` (for example, `true`) to both panels: +Trong ví dụ này, đó là component `Accordion`. Vì nó ở trên cả hai panel và có thể kiểm soát props của chúng, nó sẽ trở thành "nguồn chân lý" cho việc panel nào hiện đang active. Làm cho component `Accordion` truyền một giá trị cứng của `isActive` (ví dụ, `true`) cho cả hai panel: @@ -172,21 +172,21 @@ h3, p { margin: 5px 0px; } -Try editing the hardcoded `isActive` values in the `Accordion` component and see the result on the screen. +Thử chỉnh sửa các giá trị `isActive` cứng trong component `Accordion` và xem kết quả trên màn hình. -### Step 3: Add state to the common parent {/*step-3-add-state-to-the-common-parent*/} +### Bước 3: Thêm state vào parent chung {/*step-3-add-state-to-the-common-parent*/} -Lifting state up often changes the nature of what you're storing as state. +Lifting state lên thường thay đổi bản chất của những gì bạn đang lưu trữ dưới dạng state. -In this case, only one panel should be active at a time. This means that the `Accordion` common parent component needs to keep track of *which* panel is the active one. Instead of a `boolean` value, it could use a number as the index of the active `Panel` for the state variable: +Trong trường hợp này, chỉ một panel được active tại một thời điểm. Điều này có nghĩa là component parent chung `Accordion` cần theo dõi *panel nào* là panel active. Thay vì giá trị `boolean`, nó có thể sử dụng một số như index của `Panel` active cho biến state: ```js const [activeIndex, setActiveIndex] = useState(0); ``` -When the `activeIndex` is `0`, the first panel is active, and when it's `1`, it's the second one. +Khi `activeIndex` là `0`, panel đầu tiên đang active, và khi nó là `1`, thì là panel thứ hai. -Clicking the "Show" button in either `Panel` needs to change the active index in `Accordion`. A `Panel` can't set the `activeIndex` state directly because it's defined inside the `Accordion`. The `Accordion` component needs to *explicitly allow* the `Panel` component to change its state by [passing an event handler down as a prop](/learn/responding-to-events#passing-event-handlers-as-props): +Nhấp vào nút "Show" trong bất kỳ `Panel` nào cần thay đổi active index trong `Accordion`. Một `Panel` không thể đặt state `activeIndex` trực tiếp vì nó được định nghĩa bên trong `Accordion`. Component `Accordion` cần *cho phép rõ ràng* component `Panel` thay đổi state của nó bằng cách [truyền một event handler xuống như một prop](/learn/responding-to-events#passing-event-handlers-as-props): ```js <> @@ -205,7 +205,7 @@ Clicking the "Show" button in either `Panel` needs to change the active index in ``` -The `