mroe docs
This commit is contained in:
parent
5815a590a8
commit
e35fc79f09
3 changed files with 264 additions and 3 deletions
79
docs/keys.md
79
docs/keys.md
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
- [What are keys](#what-are-keys)
|
||||
- [How to use](#how-to-use)
|
||||
- [Debugging key related issues](#debugging-key-related-issues)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ Keys are a mechanism that allows re-ordering DOM elements within a NodeList, and
|
|||
|
||||
In other words, a `key` is a way of saying "this DOM element is for the data object with this id".
|
||||
|
||||
Typically, `key` should be the unique identifier field of the objects in the data array.
|
||||
Typically, a `key` property should be the unique identifier field of the objects in the data array.
|
||||
|
||||
```javascript
|
||||
var users = [
|
||||
|
|
@ -64,7 +65,7 @@ Worse still, if there were stateful jQuery plugins attached to these buttons, th
|
|||
|
||||
Even though in this particular example, we humans intuitively guess that the first item in the list was the one being removed, it's actually impossible for a computer to automatically solve this problem for all possible inputs.
|
||||
|
||||
Therefore, in the cases when a list of vnodes is derived from a *mutable* array of data, you should add a `key` property to each virtual node that maps to a uniquely identifiable field in the source data. This will allow Mithril to intelligently re-order the DOM to maintain each DOM element correctly mapped to its respective item in the data source.
|
||||
Therefore, in the cases when a list of vnodes is derived from a dynamic array of data, you should add a `key` property to each virtual node that maps to a uniquely identifiable field in the source data. This will allow Mithril to intelligently re-order the DOM to maintain each DOM element correctly mapped to its respective item in the data source.
|
||||
|
||||
```javascript
|
||||
function correctUserList(users) {
|
||||
|
|
@ -74,7 +75,79 @@ function correctUserList(users) {
|
|||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Debugging key related issues
|
||||
|
||||
Keys can cause confusing issues if they are misunderstood. A typical symptom of key related issues is that application state appears to become corrupted after a few user interactions (usually involving a deletion).
|
||||
|
||||
#### Avoid wrapper elements around keyed elements
|
||||
|
||||
Keys must be placed on the virtual node that is an immediate child of the array. This means that if you wrap the `button` in an `div` in the example above, the key must be moved to the `div`.
|
||||
|
||||
```javascript
|
||||
// AVOID
|
||||
users.map(function(u) {
|
||||
return m("div", [ //key should be in `div`
|
||||
m("button", {key: u.id}, u.name)
|
||||
])
|
||||
})
|
||||
```
|
||||
|
||||
#### Avoid hiding keys in component root elements
|
||||
|
||||
If you refactor the code and put the button inside a component, the key must be moved out of the component and placed back where the component took the place of the button.
|
||||
|
||||
```javascript
|
||||
// AVOID
|
||||
var Button = {
|
||||
view: function(vnode) {
|
||||
return m("button", {key: vnode.attrs.id}, u.name)
|
||||
}
|
||||
}
|
||||
users.map(function(u) {
|
||||
return m("div", [
|
||||
m(Button, {id: u.id}, u.name) //key should be here, not in component
|
||||
])
|
||||
})
|
||||
```
|
||||
|
||||
#### Avoid wrapping keyed elements in arrays
|
||||
|
||||
Arrays are [vnodes](vnodes.md), and therefore keyable. You should not wrap arrays around keyed elements
|
||||
|
||||
```javascript
|
||||
// AVOID
|
||||
users.map(function(u) {
|
||||
return [ //fragment is a vnode, and therefore keyable
|
||||
m("button", {key: u.id}, u.name)
|
||||
]
|
||||
})
|
||||
|
||||
// PREFER
|
||||
users.map(function(u) {
|
||||
return m("button", {key: u.id}, u.name)
|
||||
})
|
||||
|
||||
// PREFER
|
||||
users.map(function(u) {
|
||||
return {tag: "[", key: u.id, children: [
|
||||
m("button", u.name)
|
||||
]}
|
||||
})
|
||||
```
|
||||
|
||||
#### Avoid variable types
|
||||
|
||||
Keys must be strings if present or they will be cast to strings if they are not. Therefore, `"1"` (string) and `1` (number) are considered the same key.
|
||||
|
||||
In addition, keys must be placed on the virtual node that is an immediate child of the array. This means that if you wrap the `button` in an `div` in the example above, the key must be moved to the `div`. Likewise, if you refactor the code and put the button inside a component, the key must be moved out of the component and placed back where the component took place of the button.
|
||||
You should use either strings or numbers as keys in one array, but not mix both.
|
||||
|
||||
```javascript
|
||||
// AVOID
|
||||
var things = [
|
||||
{id: "1", name: "Book"},
|
||||
{id: 1, name: "Cup"},
|
||||
]
|
||||
```
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue