Skip to content

docs(cn): translate content/docs/lists-and-keys.md into Chinese #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 21, 2019
Merged
86 changes: 43 additions & 43 deletions content/docs/lists-and-keys.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
---
id: lists-and-keys
title: Lists and Keys
title: 列表 & Keys
permalink: docs/lists-and-keys.html
prev: conditional-rendering.html
next: forms.html
---

First, let's review how you transform lists in JavaScript.
首先,让我们看下在 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:
如下代码,我们使用 [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) 函数让数组中的每一项变双倍,然后我们得到了一个新的列表 `doubled`并打印出来:

```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.
代码打印出 `[2, 4, 6, 8, 10]`

In React, transforming arrays into lists of [elements](/docs/rendering-elements.html) is nearly identical.
React 中,把数组转化为[元素](/docs/rendering-elements.html) 列表的过程是相似的。

### Rendering Multiple Components {#rendering-multiple-components}
### 渲染多个组件 {#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 `{}`.
你可以通过使用 `{}` 在 JSX 内构建一个[元素集合](/docs/introducing-jsx.html#embedding-expressions-in-jsx)

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`:
下面,我们使用 Javascript 中的 [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) 方法来遍历 `numbers` 数组。将数组中的每个元素变成 `<li>` 标签,最后我们将得到的数组赋值给 `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):
我们把整个 `listItems` 插入到 `<ul>` 元素中,然后[渲染进 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)
[CodePen 上尝试](https://codepen.io/gaearon/pen/GjPyQr?editors=0011)

This code displays a bullet list of numbers between 1 and 5.
这段代码生成了一个 1 到 5 的项目符号列表。

### Basic List Component {#basic-list-component}
### 基础列表组件 {#basic-list-component}

Usually you would render lists inside a [component](/docs/components-and-props.html).
通常你需要在一个[组件](/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.
我们可以把前面的例子重构成一个组件,这个组件接收 `numbers` 数组作为参数并输出一个元素列表。

```javascript{3-5,7,13}
function NumberList(props) {
Expand All @@ -70,9 +70,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.
当我们运行这段代码,将会看到一个警告 `a key should be provided for list items` ,意思是当你创建一个元素时,必须包括一个特殊的 `key` 属性。我们将在下一节讨论这是为什么。

Let's assign a `key` to our list items inside `numbers.map()` and fix the missing key issue.
让我们来给每个列表元素分配一个 `key` 属性来解决上面的那个警告:

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

[**Try it on CodePen**](https://codepen.io/gaearon/pen/jrXYRR?editors=0011)
[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:
Keys 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。

```js{3}
const numbers = [1, 2, 3, 4, 5];
Expand All @@ -109,7 +109,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:
一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用来自数据 id 来作为元素的 key:

```js{2}
const todoItems = todos.map((todo) =>
Expand All @@ -119,7 +119,7 @@ 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:
当元素没有确定 id 的时候,万不得已你可以使用元素索引 index 作为 key

```js{2,3}
const todoItems = todos.map((todo, index) =>
Expand All @@ -130,23 +130,23 @@ const todoItems = todos.map((todo, index) =>
);
```

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.
如果列表项目的顺序可能会变化,我们不建议使用索引来用作键值,因为这样做会导致性能变差,还可能引起组件状态的问题。可以看看 Robin Pokorny 的[深度解析使用索引作为 key 的负面影响](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) 这一篇文章。如果你选择不指定显式的键值,那么 React 将默认使用索引用作为列表项目的键值。

Here is an [in-depth explanation about why keys are necessary](/docs/reconciliation.html#recursing-on-children) if you're interested in learning more.
要是你有兴趣了解更多的话,这里有一篇文章 [深入解析为什么 keys 是必须的](/docs/reconciliation.html#recursing-on-children) 可以参考。

### Extracting Components with Keys {#extracting-components-with-keys}
### Keys 提取组件 {#extracting-components-with-keys}

Keys only make sense in the context of the surrounding array.
元素的 Key 只有放在就近的数组上下文中才有意义。

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.
比方说,如果你[提取](/docs/components-and-props.html#extracting-components) 出一个 `ListItem` 组件,你应该把 key 保留在数组中的这个 `<ListItem />` 元素上,而不是放在 `ListItem` 组件中的 `<li>` 元素上。

**Example: Incorrect Key Usage**
** 例子:不正确的使用键的方式 **

```javascript{4,5,14,15}
function ListItem(props) {
const value = props.value;
return (
// Wrong! There is no need to specify the key here:
// 错误!你不需要在这里指定 key:
<li key={value.toString()}>
{value}
</li>
Expand All @@ -156,7 +156,7 @@ function ListItem(props) {
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Wrong! The key should have been specified here:
// 错误!元素的 key 应该在这里指定:
<ListItem value={number} />
);
return (
Expand All @@ -173,18 +173,18 @@ ReactDOM.render(
);
```

**Example: Correct Key Usage**
** 例子:正确的使用键的方式 **

```javascript{2,3,9,10}
function ListItem(props) {
// Correct! There is no need to specify the key here:
// 正确!这里不需要指定 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.
// 正确!key 应该在数组的上下文中被指定
<ListItem key={number.toString()}
value={number} />
);
Expand All @@ -202,13 +202,13 @@ ReactDOM.render(
);
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZXeOGM?editors=0010)
[CodePen 上尝试](https://codepen.io/gaearon/pen/ZXeOGM?editors=0010)

A good rule of thumb is that elements inside the `map()` call need keys.
一个好的经验法则是:在 `map()` 方法中的元素需要设置 keys 属性。

### Keys Must Only Be Unique Among Siblings {#keys-must-only-be-unique-among-siblings}
### 键(Key)只是在兄弟节点之间必须唯一 {#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:
数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的键:

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

[**Try it on CodePen**](https://codepen.io/gaearon/pen/NRZYGN?editors=0010)
[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:
key 会传递信息给 React ,但不会传递给你的组件。如果你的组件中需要使用 `key` 属性的值,请用其他属性名显式传递这个值:

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

With the example above, the `Post` component can read `props.id`, but not `props.key`.
上面例子中,`Post` 组件可以读出 `props.id`,但是不能读出 `props.key`

### Embedding map() in JSX {#embedding-map-in-jsx}
### 在 JSX 中嵌入 map() {#embedding-map-in-jsx}

In the examples above we declared a separate `listItems` variable and included it in JSX:
在上面的例子中,我们声明了一个单独的 `listItems` 变量并将其包含在 JSX 中:

```js{3-6}
function NumberList(props) {
Expand All @@ -280,7 +280,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 允许在大括号中[嵌入任何表达式](/docs/introducing-jsx.html#embedding-expressions-in-jsx),所以我们可以内联 `map()` 返回的结果:

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

[**Try it on CodePen**](https://codepen.io/gaearon/pen/BLvYrB?editors=0010)
[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).
这么做有时可以使你的代码更清晰,但有时这种风格也会被滥用。就像在 JavaScript 中一样,何时需要为了可读性提取出一个变量,这完全取决于你。但请记住,如果一个 `map()` 嵌套了太多层级,那可能就是你 [提取出组件](/docs/components-and-props.html#extracting-components) 的一个好时机。