You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a list is re-rendered, React takes each list item's key and searches the previous list's items for a matching key. If the current list has a key that didn't exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding component is moved. Keys tell React about the identity of each component which allows React to maintain state between re-renders. If a component's key changes, the component will be destroyed and re-created with a new state.
`key`is a special and reserved property in React (along with `ref`, a more advanced feature). When an element is created, React extracts the `key`property and stores the key directly on the returned element. Even though `key`may look like it belongs in `props`, `key` cannot be referenced using `this.props.key`. React automatically uses `key`to decide which components to update. A component cannot inquire about its `key`.
**It's strongly recommended that you assign proper keys whenever you build dynamic lists.**If you don't have an appropriate key, you may want to consider restructuring your data so that you do.
If no key is specified, React will present a warning and use the array index as a key by default. Using the array index as a key is problematic when trying to re-order a list's items or inserting/removing list items. Explicitly passing `key={i}`silences the warning but has the same problems as array indices and is not recommended in most cases.
Keys do not need to be globally unique; they only need to be unique between components and their siblings.
1105
+
组件的 key 的值并不需要在全局都保证唯一,只需要在当前的节点里保证唯一即可。
1106
1106
1107
1107
1108
-
### Implementing Time Travel
1108
+
### 实现时间旅行
1109
1109
1110
-
In the tic-tac-toe game's history, each past move has a unique ID associated with it: it's the sequential number of the move. The moves are never re-ordered, deleted, or inserted in the middle, so it's safe to use the move index as a key.
1110
+
在井字游戏的历史记录中,每一个历史步骤都有一个与之对应的唯一 ID:这个 ID 就是每一步棋的序号,。因为历史步骤不需要重新排序,或者新增、删除,所以使用步骤的索引作为 `key` 是安全的。
1111
1111
1112
-
In the Game component's`render`method, we can add the key as `<li key={move}>` and React's warning about keys should disappear:
1112
+
在 Game 组件的`render`方法中,我们可以这样添加 key,`<li key={move}>`,这样关于 key 的警告就会消失了。
1113
1113
1114
1114
```js{6}
1115
1115
const moves = history.map((step, move) => {
@@ -1124,11 +1124,11 @@ In the Game component's `render` method, we can add the key as `<li key={move}>`
1124
1124
});
1125
1125
```
1126
1126
1127
-
**[View the full code at this point](https://codepen.io/gaearon/pen/PmmXRE?editors=0010)**
Clicking any of the list item's buttons throws an error because the `jumpTo`method is undefined. Before we implement `jumpTo`, we'll add `stepNumber` to the Game component's state to indicate which step we're currently viewing.
1129
+
因为 `jumpTo`还没有定义,所以你点击列表项的按钮时,会出现报错,。在我们实现 `jumpTo` 之前,我们向 Game 组件的 state 中添加 `stepNumber`,这个值代表我们当前正在看哪一项历史记录。
1130
1130
1131
-
First, add `stepNumber: 0` to the initial state in Game's `constructor`:
1131
+
首先,我们在 Game 的构造函数 `constructor` 中向初始 state 中添加 `stepNumber: 0`:
1132
1132
1133
1133
```js{8}
1134
1134
class Game extends React.Component {
@@ -1144,11 +1144,11 @@ class Game extends React.Component {
1144
1144
}
1145
1145
```
1146
1146
1147
-
Next, we'll define the `jumpTo`method in Game to update that `stepNumber`. We also set `xIsNext` to true if the number that we're changing `stepNumber` to is even:
1147
+
然后我们在 Game 组件中定义 `jumpTo`方法以更新上述的 `stepNumber`。除此之外,如果我们将要改变的 `stepNumber` 是偶数时,我们还要把 `xIsNext` 设为 true:
1148
1148
1149
1149
```javascript{5-10}
1150
1150
handleClick(i) {
1151
-
// this method has not changed
1151
+
// 这个方法无更改
1152
1152
}
1153
1153
1154
1154
jumpTo(step) {
@@ -1159,15 +1159,15 @@ Next, we'll define the `jumpTo` method in Game to update that `stepNumber`. We a
1159
1159
}
1160
1160
1161
1161
render() {
1162
-
// this method has not changed
1162
+
// 这个方法无更改
1163
1163
}
1164
1164
```
1165
1165
1166
-
We will now make a few changes to the Game's `handleClick`method which fires when you click on a square.
1166
+
接下来,我们还要对 Game 组件的 `handleClick`方法做一些修改,这个方法会在你点击方格的时候触发。
1167
1167
1168
-
The`stepNumber` state we've added reflects the move displayed to the user now. After we make a new move, we need to update `stepNumber` by adding `stepNumber: history.length`as part of the `this.setState`argument. This ensures we don't get stuck showing the same move after a new one has been made.
1168
+
我们刚才添加的`stepNumber` state 反映了给用户展示的当前步骤。每当我们下一步新棋子的时候,我们需要把 `stepNumber: history.length`添加为 `this.setState`的参数的一部分,以更新 `stepNumber`。这就保证了保证每走一步 `stepNumber` 会跟着改变。
1169
1169
1170
-
We will also replace reading `this.state.history` with `this.state.history.slice(0, this.state.stepNumber + 1)`. This ensures that if we "go back in time" and then make a new move from that point, we throw away all the "future" history that would now become incorrect.
1170
+
We will also replace reading `this.state.history` with `this.state.history.slice(0, this.state.stepNumber + 1)`. This ensures that if we "go back in time" and then make a new move from that point, we throw away all the "future" history that would now become incorrect.我们还把读取 `this.state.history` 换成了 `this.state.history.slice(0, this.state.stepNumber + 1)`。如果我们“回到过去”,然后在走一步新棋子,原来的“未来”历史记录就不正确了,这个替换可以保证我们把这些“未来”的不正确的历史记录丢弃掉。
1171
1171
1172
1172
```javascript{2,13}
1173
1173
handleClick(i) {
@@ -1188,7 +1188,7 @@ We will also replace reading `this.state.history` with `this.state.history.slice
1188
1188
}
1189
1189
```
1190
1190
1191
-
Finally, we will modify the Game component's`render`method from always rendering the last move to rendering the currently selected move according to `stepNumber`:
1191
+
最后一步,我们把 Game 组件的`render`方法从总是渲染最后一步更改为,根据 stepNumber` 渲染当前选择的步骤。
1192
1192
1193
1193
```javascript{3}
1194
1194
render() {
@@ -1199,30 +1199,30 @@ Finally, we will modify the Game component's `render` method from always renderi
1199
1199
// the rest has not changed
1200
1200
```
1201
1201
1202
-
If we click on any step in the game's history, the tic-tac-toe board should immediately update to show what the board looked like after that step occurred.
1202
+
如果我们点击游戏历史记录的任何一步,井字游戏的棋盘就会立即更新为刚刚下那一步棋时候的样子。
1203
1203
1204
-
**[View the full code at this point](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**
If you have extra time or want to practice your new React skills, here are some ideas for improvements that you could make to the tic-tac-toe game which are listed in order of increasing difficulty:
1.Display the location for each move in the format (col, row) in the move history list.
1222
-
2.Bold the currently selected item in the move list.
1223
-
3.Rewrite Board to use two loops to make the squares instead of hardcoding them.
1224
-
4.Add a toggle button that lets you sort the moves in either ascending or descending order.
1225
-
5.When someone wins, highlight the three squares that caused the win.
1226
-
6.When no one wins, display a message about the result being a draw.
1221
+
1.在游戏历史记录列表显示每一步棋的坐标,格式为 (列号, 行号)。
1222
+
2.在历史记录列表中加粗显示当前选择的项目。
1223
+
3.使用两个循环来渲染出棋盘的格子,而不是在代码里写死(hardcode)。
1224
+
4.添加一个可以升序或降序排列历史记录的按钮。
1225
+
5.每当有人获胜时,高亮显示连成一线的 3 颗棋子。
1226
+
6.当没有人获胜时,显示一个平局的消息。
1227
1227
1228
-
Throughout this tutorial, we touched on React concepts including elements, components, props, and state. For a more detailed explanation of each of these topics, check out [the rest of the documentation](/docs/hello-world.html). To learn more about defining components, check out the [`React.Component` API reference](/docs/react-component.html).
1228
+
通过这一篇教程,我们接触了 React 中的一些概念,比如 React 元素、React 组件、props,还有 state。更多关于这些概念的细节的解释,参考 [文档的其他部分](/docs/hello-world.html)。了解更多关于组件定义的内容,参考[`React.Component` API reference](/docs/react-component.html)。
0 commit comments