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
React provides a declarative API so that you don't have to worry about exactly what changes on every update. This makes writing applications a lot easier, but it might not be obvious how this is implemented within React. This article explains the choices we made in React's "diffing" algorithm so that component updates are predictable while being fast enough for high-performance apps.
7
+
React は、各更新で実際に何が変更されるべきかを人間が心配する必要がないように、宣言型の API を提供しています。これによりアプリケーションの作成が大幅に容易になるわけですが、React の中でこの処理がどのように実装されているのかはよく分からないかもしれません。この章では React の "差分" アルゴリズムについて、コンポーネントの更新を予測可能なものとしながら、ハイパフォーマンスなアプリケーションの要求を満たす速度を得られるように、私たちが行った選択について説明します。
8
8
9
-
## Motivation {#motivation}
9
+
## 何が問題なのか {#motivation}
10
10
11
-
When you use React, at a single point in time you can think of the `render()`function as creating a tree of React elements. On the next state or props update, that `render()`function will return a different tree of React elements. React then needs to figure out how to efficiently update the UI to match the most recent tree.
There are some generic solutions to this algorithmic problem of generating the minimum number of operations to transform one tree into another. However, the [state of the art algorithms](http://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf) have a complexity in the order of O(n<sup>3</sup>) where n is the number of elements in the tree.
13
+
あるツリーを別のものに変換するための最小限の操作を求めるというアルゴリズム問題については、いくつかの一般的な解決方法が存在しています。しかし、[最新のアルゴリズム](http://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf)でもツリーの要素数を n として O(n<sup>3</sup>) ほどの計算量があります。
14
14
15
-
If we used this in React, displaying 1000 elements would require in the order of one billion comparisons. This is far too expensive. Instead, React implements a heuristic O(n) algorithm based on two assumptions:
### Elements Of Different Types {#elements-of-different-types}
26
+
### 異なる型の要素 {#elements-of-different-types}
27
27
28
-
Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. Going from `<a>`to`<img>`, or from `<Article>`to`<Comment>`, or from `<Button>`to`<div>`- any of those will lead to a full rebuild.
When tearing down a tree, old DOM nodes are destroyed. Component instances receive `componentWillUnmount()`. When building up a new tree, new DOM nodes are inserted into the DOM. Component instances receive `componentWillMount()`and then `componentDidMount()`. Any state associated with the old tree is lost.
30
+
ツリーを破棄する時点で、古い DOM ノードは破棄されます。コンポーネントのインスタンスは `componentWillUnmount()` を受け取ります。新しいツリーを構築する時点で、新しい DOM ノードが DOM に挿入されます。コンポーネントのインスタンスは `componentWillMount()`とそれから `componentDidMount()` を受け取ります。古いツリーに関連付けられた全ての state は失われます。
31
31
32
-
Any components below the root will also get unmounted and have their state destroyed. For example, when diffing:
32
+
ルート配下のコンポーネントはアンマウントされ、それらの state は破棄されます。例えば、以下のように異なる場合:
33
33
34
34
```xml
35
35
<div>
@@ -41,43 +41,43 @@ Any components below the root will also get unmounted and have their state destr
41
41
</span>
42
42
```
43
43
44
-
This will destroy the old `Counter`and remount a new one.
44
+
古い `Counter`は破棄され、新しいものが再マウントされます。
45
45
46
-
### DOM Elements Of The Same Type {#dom-elements-of-the-same-type}
46
+
### 同じ型の DOM 要素 {#dom-elements-of-the-same-type}
47
47
48
-
When comparing two React DOM elements of the same type, React looks at the attributes of both, keeps the same underlying DOM node, and only updates the changed attributes. For example:
48
+
同じ型の 2 つの React DOM 要素を比較した場合、React はそれぞれの属性を調べ、対応する共通の DOM ノードを保持し、変更された属性のみを更新します。例えば:
49
49
50
50
```xml
51
51
<divclassName="before"title="stuff" />
52
52
53
53
<divclassName="after"title="stuff" />
54
54
```
55
55
56
-
By comparing these two elements, React knows to only modify the `className`on the underlying DOM node.
56
+
これらの2つの要素を比べた場合、React は対応する DOM ノードの `className`のみを更新すればよいと分かります。
57
57
58
-
When updating `style`, React also knows to update only the properties that changed. For example:
When a component updates, the instance stays the same, so that state is maintained across renders. React updates the props of the underlying component instance to match the new element, and calls `componentWillReceiveProps()`and`componentWillUpdate()`on the underlying instance.
72
+
コンポーネントが更新される場合、インスタンスは同じままとなり、レンダー間で state は保持されます。React は対応するコンポーネントのインスタンスの props を新しい要素に合うように更新し、`componentWillReceiveProps()`と`componentWillUpdate()`を対応するインスタンスに対して呼び出します。
73
73
74
-
Next, the `render()`method is called and the diff algorithm recurses on the previous result and the new result.
### Recursing On Children {#recursing-on-children}
76
+
### 子要素の再帰的な処理 {#recursing-on-children}
77
77
78
-
By default, when recursing on the children of a DOM node, React just iterates over both lists of children at the same time and generates a mutation whenever there's a difference.
If you implement it naively, inserting an element at the beginning has worse performance. For example, converting between these two trees works poorly:
97
+
それを単純に実行した場合、先頭への要素の追加はパフォーマンスが悪くなります。
98
98
99
99
```xml
100
100
<ul>
@@ -109,11 +109,11 @@ If you implement it naively, inserting an element at the beginning has worse per
109
109
</ul>
110
110
```
111
111
112
-
React will mutate every child instead of realizing it can keep the `<li>Duke</li>`and`<li>Villanova</li>`subtrees intact. This inefficiency can be a problem.
In order to solve this issue, React supports a `key`attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree. For example, adding a `key`to our inefficient example above can make the tree conversion efficient:
In practice, finding a key is usually not hard. The element you are going to display may already have a unique ID, so the key can just come from your data:
133
+
実際に、key を探すのはたいてい難しくありません。表示しようとしている要素は既に固有の ID を持っているかもしれないので、key をそのデータから設定するだけです。
134
134
135
135
```js
136
136
<li key={item.id}>{item.name}</li>
137
137
```
138
138
139
-
When that's not the case, you can add a new ID property to your model or hash some parts of the content to generate a key. The key only has to be unique among its siblings, not globally unique.
139
+
そうではない場合には、新しい ID プロパティをモデルに追加するか、key を生成するためにコンテンツの一部をハッシュ化します。key は兄弟要素間で一意であればよく、グローバルに一意である必要はありません。
140
140
141
-
As a last resort, you can pass an item's index in the array as a key. This can work well if the items are never reordered, but reorders will be slow.
Reorders can also cause issues with component state when indexes are used as keys. Component instances are updated and reused based on their key. If the key is an index, moving an item changes it. As a result, component state for things like uncontrolled inputs can get mixed up and updated in unexpected ways.
[Here](codepen://reconciliation/index-used-as-key) is an example of the issues that can be caused by using indexes as keys on CodePen, and [here](codepen://reconciliation/no-index-used-as-key) is an updated version of the same example showing how not using indexes as keys will fix these reordering, sorting, and prepending issues.
It is important to remember that the reconciliation algorithm is an implementation detail. React could rerender the whole app on every action; the end result would be the same. Just to be clear, rerender in this context means calling `render`for all components, it doesn't mean React will unmount and remount them. It will only apply the differences following the rules stated in the previous sections.
We are regularly refining the heuristics in order to make common use cases faster. In the current implementation, you can express the fact that a subtree has been moved amongst its siblings, but you cannot tell that it has moved somewhere else. The algorithm will rerender that full subtree.
1.The algorithm will not try to match subtrees of different component types. If you see yourself alternating between two component types with very similar output, you may want to make it the same type. In practice, we haven't found this to be an issue.
2.Keys should be stable, predictable, and unique. Unstable keys (like those produced by `Math.random()`) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.
157
+
2.key は予測可能で安定した、一意なものであるべきです。不安定な key(例えば `Math.random()` 関数で生成するような)は多くのコンポーネントのインスタンスと DOM ノードを不必要に再生成し、パフォーマンスの低下や子コンポーネントの state の喪失を引き起こします。
0 commit comments