Skip to content

Commit

Permalink
Merge pull request #19 from NhanHoang8195/translate/lists-and-keys
Browse files Browse the repository at this point in the history
Translate lists and keys
  • Loading branch information
ltmylinh committed Mar 10, 2019
2 parents 3d66a8f + 5710384 commit 6a7d96a
Showing 1 changed file with 47 additions and 45 deletions.
92 changes: 47 additions & 45 deletions content/docs/lists-and-keys.md
@@ -1,30 +1,30 @@
---
id: lists-and-keys
title: Lists and Keys
title: Lists Keys
permalink: docs/lists-and-keys.html
prev: conditional-rendering.html
next: forms.html
---

First, let's review how you transform lists in JavaScript.
Đầu tiên, hãy xem lại cách bạn chuyển đổi "danh sách" (lists) trong Javascript.

Given the code below, we use the [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function to take an array of `numbers` and double their values. We assign the new array returned by `map()` to the variable `doubled` and log it:
Trong đoạn code bên dưới, chúng ta sử dụng hàm [`map()`](https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Array/map) để nhân đôi giá trị của từng phần tử trong mảng `numbers`. Chúng ta gán mảng mới là kết quả trả về từ hàm `map()` vào biến `doubled` và xuất kết quả đó ra:

```javascript{2}
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
```

This code logs `[2, 4, 6, 8, 10]` to the console.
Đoạn code trên xuất kết quả `[2, 4, 6, 8, 10]` ra màn hình console.

In React, transforming arrays into lists of [elements](/docs/rendering-elements.html) is nearly identical.
Trong React, việc chuyển đổi mảng các phần tử thành danh sách (arrays into lists) của các [element](/docs/rendering-elements.html) là gần như giống hệt nhau.

### Rendering Multiple Components {#rendering-multiple-components}
### Render Nhiều Component {#rendering-multiple-components}

You can build collections of elements and [include them in JSX](/docs/introducing-jsx.html#embedding-expressions-in-jsx) using curly braces `{}`.
Bạn có thể xây dựng nhiều tập hợp (collections) của các element và [nhúng những tập hợp element này vào JSX](/docs/introducing-jsx.html#embedding-expressions-in-jsx) bằng việc sử dụng dấu ngoặc nhọn `{}`.

Below, we loop through the `numbers` array using the JavaScript [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function. We return a `<li>` element for each item. Finally, we assign the resulting array of elements to `listItems`:
Dưới đây, chúng ta sử dụng vòng lặp trên mảng `numbers` và sử dụng hàm [`map()`](https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Array/map) trong JavaScript. Kết quả trả về là một thẻ `<li>` cho mỗi vòng lặp. Cuối cùng, chúng ta gán mảng kết quả gồm những element (thẻ `<li>`) cho `listItems`:

```javascript{2-4}
const numbers = [1, 2, 3, 4, 5];
Expand All @@ -33,7 +33,7 @@ const listItems = numbers.map((number) =>
);
```

We include the entire `listItems` array inside a `<ul>` element, and [render it to the DOM](/docs/rendering-elements.html#rendering-an-element-into-the-dom):
Chúng ta nhúng toàn bộ `listItems` vào trong thẻ `<ul>` , và [render mảng này ra DOM](/docs/rendering-elements.html#rendering-an-element-into-the-dom):

```javascript{2}
ReactDOM.render(
Expand All @@ -42,15 +42,15 @@ ReactDOM.render(
);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/GjPyQr?editors=0011)
[**Thử trên CodePen**](https://codepen.io/gaearon/pen/GjPyQr?editors=0011)

This code displays a bullet list of numbers between 1 and 5.
Đoạn code trên hiển thị một danh sách từ 1 đến 5 và có chứa các dấu chấm tròn trước mỗi số.

### Basic List Component {#basic-list-component}
### Component Có Danh Sách Cơ Bản (Basic List Component) {#basic-list-component}

Usually you would render lists inside a [component](/docs/components-and-props.html).
Thông thường bạn sẽ render các danh sách trong một [component](/docs/components-and-props.html).

We can refactor the previous example into a component that accepts an array of `numbers` and outputs a list of elements.
Chúng ta có thể điều chỉnh để đưa đoạn code trong ví dụ trước vào một component và trong component đó sẽ nhận một mảng `numbers` và xuất ra danh sách các element.

```javascript{3-5,7,13}
function NumberList(props) {
Expand All @@ -59,7 +59,9 @@ function NumberList(props) {
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
<ul>{listItems}</u
l>
);
}
Expand All @@ -70,9 +72,9 @@ ReactDOM.render(
);
```

When you run this code, you'll be given a warning that a key should be provided for list items. A "key" is a special string attribute you need to include when creating lists of elements. We'll discuss why it's important in the next section.
Khi bạn chạy đoạn code này, bạn sẽ nhận một thông báo lưu ý rằng một thuộc tính key nên được truyền vào cho mỗi phần tử (thẻ `<li>` bên trong hàm `map()`). Một "key" là một thuộc tính chuỗi đặc biệt bạn cần phải đưa vào khi tạo danh sách các element. Chúng ta sẽ thảo luận tại sao điều này lại quan trọng trong mục kế tiếp.

Let's assign a `key` to our list items inside `numbers.map()` and fix the missing key issue.
Hãy gán `key` vào từng phần tử của chúng ta bên trong `numbers.map()` và sửa cảnh báo bị thiếu key lúc nãy.

```javascript{4}
function NumberList(props) {
Expand All @@ -94,11 +96,11 @@ ReactDOM.render(
);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/jrXYRR?editors=0011)
[**Thử trên CodePen**](https://codepen.io/gaearon/pen/jrXYRR?editors=0011)

## Keys {#keys}

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
Các key giúp React xác định những phần tử nào đã thay đổi, được thêm, hay bị xóa. Các key nên được truyền vào các element bên trong một mảng để cho các element này có một định danh cố định (stable identity):

```js{3}
const numbers = [1, 2, 3, 4, 5];
Expand All @@ -109,7 +111,7 @@ const listItems = numbers.map((number) =>
);
```

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys:
Các tốt nhất để chọn một key là sử dụng một chuỗi mà được xác định là duy nhất trong các nút anh em (siblings). Cách thông thường nhất mà bạn sẽ sử dụng là dùng các ID từ dữ liệu của bạn làm key:

```js{2}
const todoItems = todos.map((todo) =>
Expand All @@ -119,34 +121,34 @@ const todoItems = todos.map((todo) =>
);
```

When you don't have stable IDs for rendered items, you may use the item index as a key as a last resort:
Khi bạn không có các ID cố định (stable IDs) cho việc render các phần tử, bạn có thể sử dụng thứ tự của phần tử đó trong danh sách như là một key cũng như là một phương án cuối cùng:

```js{2,3}
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
// Chỉ làm điều này khi không có ID cố định
<li key={index}>
{todo.text}
</li>
);
```

We don't recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. Check out Robin Pokorny's article for an [in-depth explanation on the negative impacts of using an index as a key](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318). If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
Chúng tôi không khuyến khích sử dụng thứ tự của các phần tử cho các key nếu thứ tự của các phần tử có thể thay đổi. Điều này có thể ảnh hưởng đến hiệu suất và có thể gây ra một vài vấn đề với state của component. Xem qua bài viết của Robin Pokorny về việc [giải thích ảnh hưởng tiêu cực của việc sử dụng thứ tự phần tử cho key](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318). Nếu bạn lựa chọn việc không gán cho key một định danh rõ ràng thì mặc định React sẽ sử dựng thứ tự của phần tử cho key.

Here is an [in-depth explanation about why keys are necessary](/docs/reconciliation.html#recursing-on-children) if you're interested in learning more.
Xem thêm [giải thích về việc tại sao các key là cần thiết](/docs/reconciliation.html#recursing-on-children) nếu bạn quan tâm nhiều về vấn đề này.

### Extracting Components with Keys {#extracting-components-with-keys}
### Chia Nhỏ Các Component Với Key {#extracting-components-with-keys}

Keys only make sense in the context of the surrounding array.
Các key chỉ hợp lí trong trường hợp liên quan đến mảng dữ liệu.

For example, if you [extract](/docs/components-and-props.html#extracting-components) a `ListItem` component, you should keep the key on the `<ListItem />` elements in the array rather than on the `<li>` element in the `ListItem` itself.
Ví dụ, nếu bạn [chia nhỏ](/docs/components-and-props.html#extracting-components) component `ListItem`, bạn nên giữ việc truyền key vào các `<ListItem />` element trong mảng thay vì truyền vào thẻ `<li>` bên trong `ListItem` element.

**Example: Incorrect Key Usage**
**Ví dụ: Trường hợp sử dụng key chưa chính xác**

```javascript{4,5,14,15}
function ListItem(props) {
const value = props.value;
return (
// Wrong! There is no need to specify the key here:
// Sai! Ở đây không cần truyền vào key:
<li key={value.toString()}>
{value}
</li>
Expand All @@ -156,7 +158,7 @@ function ListItem(props) {
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Wrong! The key should have been specified here:
// Sai! Key nên được truyền vào ở đây:
<ListItem value={number} />
);
return (
Expand All @@ -173,18 +175,18 @@ ReactDOM.render(
);
```

**Example: Correct Key Usage**
**Ví dụ: Trường hợp sử dụng key chính xác**

```javascript{2,3,9,10}
function ListItem(props) {
// Correct! There is no need to specify the key here:
// Đúng! Ở đây không cần cụ thể key:
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Correct! Key should be specified inside the array.
// Đúng! Key nên được cụ thể bên trong mảng.
<ListItem key={number.toString()}
value={number} />
);
Expand All @@ -202,13 +204,13 @@ ReactDOM.render(
);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZXeOGM?editors=0010)
[**Thử trên CodePen**](https://codepen.io/gaearon/pen/ZXeOGM?editors=0010)

A good rule of thumb is that elements inside the `map()` call need keys.
Một nguyên tắc nhỏ đó là các element bên trong hàm gọi `map()` cần các key.

### Keys Must Only Be Unique Among Siblings {#keys-must-only-be-unique-among-siblings}
### Các Key Chỉ Bắt Buộc Là Duy Nhất Giữa Các Nút Anh Em (Siblings) {#keys-must-only-be-unique-among-siblings}

Keys used within arrays should be unique among their siblings. However they don't need to be globally unique. We can use the same keys when we produce two different arrays:
Các Key được sử dụng bên trong các mảng nên là duy nhất giữa các nút anh em của chúng. Tuy nhiên chúng không cần là duy nhất đối với toàn bộ component. Chúng ta có thể sử dụng các key giống nhau khi chúng ta tạo hai mảng khác nhau:

```js{2,5,11,12,19,21}
function Blog(props) {
Expand Down Expand Up @@ -246,9 +248,9 @@ ReactDOM.render(
);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/NRZYGN?editors=0010)
[**Thử trên CodePen**](https://codepen.io/gaearon/pen/NRZYGN?editors=0010)

Keys serve as a hint to React but they don't get passed to your components. If you need the same value in your component, pass it explicitly as a prop with a different name:
Các key được sử dụng để gợi ý cho React nhưng chúng không được truyền vào cho các component (Nghĩa là các component con sẽ không đọc được prop.key). Nếu bạn cần đọc giá trị giống với giá trị của key bên trong component của bạn, truyền giá trị đó như một prop với một cái tên khác:

```js{3,4}
const content = posts.map((post) =>
Expand All @@ -259,11 +261,11 @@ const content = posts.map((post) =>
);
```

With the example above, the `Post` component can read `props.id`, but not `props.key`.
Với ví dụ bên trên, component `Post` có thể đọc giá trị của `props.id`, mà không phải là `props.key`.

### Embedding map() in JSX {#embedding-map-in-jsx}
### Nhúng map() vào JSX {#embedding-map-in-jsx}

In the examples above we declared a separate `listItems` variable and included it in JSX:
Trong các ví dụ trên chúng ta đã khái báo `listItems` thành một biến riêng biệt và đưa nó vào JSX:

```js{3-6}
function NumberList(props) {
Expand All @@ -280,7 +282,7 @@ function NumberList(props) {
}
```

JSX allows [embedding any expression](/docs/introducing-jsx.html#embedding-expressions-in-jsx) in curly braces so we could inline the `map()` result:
JSX cho phép [nhúng expression](/docs/introducing-jsx.html#embedding-expressions-in-jsx) bất kì vào trong dấu ngoặc nhọn vì vậy chúng ta có thể xuất kết quả của hàm `map()` như sau:

```js{5-8}
function NumberList(props) {
Expand All @@ -296,6 +298,6 @@ function NumberList(props) {
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/BLvYrB?editors=0010)
[**Thử trên CodePen**](https://codepen.io/gaearon/pen/BLvYrB?editors=0010)

Sometimes this results in clearer code, but this style can also be abused. Like in JavaScript, it is up to you to decide whether it is worth extracting a variable for readability. Keep in mind that if the `map()` body is too nested, it might be a good time to [extract a component](/docs/components-and-props.html#extracting-components).
Thỉnh thoảng cách làm như trên làm code gọn gàng hơn, nhưng kiểu này cũng có thể bị lạm dụng. Như trong JavaScript, đôi khi bạn phải quyết định xem có cần phải tạo thêm một biến để cho dễ đọc hay không. Hãy nhớ rằng nếu bên trong hàm `map()` bị lồng (nested) quá nhiều, đó có thể là lúc thích hợp để [chia nhỏ một component](/docs/components-and-props.html#extracting-components).

0 comments on commit 6a7d96a

Please sign in to comment.