Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 47 additions & 9 deletions docs/docs/09.6-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,23 @@ Dealing with immutable data in JavaScript is more difficult than in languages de

If you mutate data like this:

```javascript
```js
myData.x.y.z = 7;
// or...
myData.a.b.push(9);
```

you have no way of determining which data has changed since the previous copy is destroyed. Instead, you need to create a new copy of `myData` and change only the parts of it that need to be changed. Then you can compare the old copy of `myData` with the new one in `shouldComponentUpdate()` using triple-equals:
you have no way of determining which data has changed since the previous copy is overriden. Instead, you need to create a new copy of `myData` and change only the parts of it that need to be changed. Then you can compare the old copy of `myData` with the new one in `shouldComponentUpdate()` using triple-equals:

```javascript
```js
var newData = deepCopy(myData);
newData.x.y.z = 7;
newData.a.b.push(9);
```

Unfortunately, deep copies are expensive, and sometimes impossible. You can alleviate this by only copying objects that need to be changed and by reusing the objects that haven't changed. Unfortunately, in today's JavaScript this can be cumbersome:

```javascript
```js
var newData = extend(myData, {
x: extend(myData.x, {
y: extend(myData.x.y, {z: 7}),
Expand All @@ -42,7 +43,7 @@ While this is fairly performant (since it only shallow copies `log n` objects an

`update()` provides simple syntactic sugar around this pattern to make writing this code easier. This code becomes:

```javascript
```js
var newData = React.addons.update(myData, {
x: {y: {z: {$set: 7}}},
a: {b: {$push: [9]}}
Expand All @@ -55,8 +56,45 @@ The `$`-prefixed keys are called *commands*. The data structure they are "mutati

## Available commands

* `{$push: array}` `push()` all the items in `array` on the target
* `{$unshift: array}` `unshift()` all the items in `array` on the target
* `{$push: array}` `push()` all the items in `array` on the target.
* `{$unshift: array}` `unshift()` all the items in `array` on the target.
* `{$splice: array of arrays}` for each item in `array()` call `splice()` on the target with the parameters provided by the item.
* `{$set: any}` replace the target entirely
* `{$merge: object}` merge the keys of `object` with the target
* `{$set: any}` replace the target entirely.
* `{$merge: object}` merge the keys of `object` with the target.
* `{$apply: function}` passes in the current value to the function and updates it with the new returned value.

## Examples

### Simple push

```js
var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
```
`initialArray` is still `[1, 2, 3]`.

### Nested collections

```js
var collection = [1, 2, {a: [12, 17, 15]}];
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I am not a huge fan generally of non-homogeneous arrays…)

var newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
// => [1, 2, {a: [12, 13, 14, 15]}]
```
This accesses `collection`'s index `2`, key `a`, and does a splice of one item starting from index `1` (to remove `17`) while inserting `13` and `14`.

### Updating a value based on its current one

```js
var obj = {a: 5, b: 3};
var newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});
// => {a: 5, b: 6}
// This is equivalent, but gets verbose for deeply nested collections:
var newObj2 = update(obj, {b: {$set: obj.b * 2}});
```

### (Shallow) merge

```js
var obj = {a: 5, b: 3};
var newObj = update(obj, {$merge: {b: 6, c: 7}}); // => {a: 5, b: 6, c: 7}
```