From 11d66ab34fa31977deaf0ec27ce96f10c05ddf88 Mon Sep 17 00:00:00 2001 From: nateeo Date: Mon, 15 Jan 2018 21:32:27 +1300 Subject: [PATCH 1/3] Add common immutable update recipes and libraries --- content/docs/immutable-updates.md | 91 +++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 content/docs/immutable-updates.md diff --git a/content/docs/immutable-updates.md b/content/docs/immutable-updates.md new file mode 100644 index 00000000000..e9493bffeb7 --- /dev/null +++ b/content/docs/immutable-updates.md @@ -0,0 +1,91 @@ +--- +id: immutable-updates +title: Immutable Updates +permalink: docs/immutable-updates.html +layout: docs +--- + +To ensure immutability without performing expensive deep cloning, it is good practice to replace only the values which need updating and to reuse the rest of the original object. + +### Updating Object Properties + +To update an object property, you can make use of the [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): + +```javascript +const newData = { + ...oldData, + propertyToUpdate: newValue +}; +``` + +or by using [Object.assign{}](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): + +```javascript +const newData = Object.assign({}, oldData, { + propertyToUpdate: newValue +}); +``` + +To update a nested property such as `oldData.first.second.propertyToUpdate` you should remember to copy all of the original object's levels: + +```javascript +const newData = { + ...oldData, + first: { + ...oldData.first, + second: { + ...oldData.first.second, + propertyToUpdate: newValue + } + } +}; +``` + +### Updating Arrays + +When updating arrays, you should avoid using mutative functions such as `push`, `unshift`, and `splice` directly on the data. You can still use these functions if you copy the array first - an easy way to do so is with [Array.slice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice). + +Adding to an array using the spread syntax or [Array.concat()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat): + +```javascript +const newArray = [...oldArray, newItem ]; + +// or with concat + +const newArray = oldArray.concat(newItemArray, newItem); +``` + +Inserting or removing an item by mutating a copy: + +```javascript + +let newArray = oldArray.slice(); // create a shallow clone of oldArray + +newArray.splice(insertIndex, 0, newItem); // inserting + +newArray.splice(removeIndex, 1); // removing + +``` + +or without mutating a copy: + +```javascript +// inserting +const newArray = [ + ...oldArray.slice(0, insertIndex), + newItem, + ...oldArray.slice(insertIndex) + ]; + +// removing +const newArray = [ + ...oldArray.slice(0, removeIndex), + ...oldArray.slice(removeIndex + 1) +]; +``` + +## Utility Libraries + +There are many libraries such as [Immutable.js](https://facebook.github.io/immutable-js/) and [immutability-helper](https://github.com/kolodny/immutability-helper) that make dealing with immutable data a lot easier. They provide a more concise and readable syntax to performing immutable updates and some are optimised to perform immutable updates more efficiently than the approaches above. + + From 3d56ce3da9b95a21910bbe3c48911d0b94b3e0b8 Mon Sep 17 00:00:00 2001 From: Nathan Hur Date: Tue, 16 Jan 2018 10:23:57 +1300 Subject: [PATCH 2/3] Reorder standard vs proposal approaches to property updates --- content/docs/immutable-updates.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/docs/immutable-updates.md b/content/docs/immutable-updates.md index e9493bffeb7..1d7cf29f8b0 100644 --- a/content/docs/immutable-updates.md +++ b/content/docs/immutable-updates.md @@ -9,21 +9,21 @@ To ensure immutability without performing expensive deep cloning, it is good pra ### Updating Object Properties -To update an object property, you can make use of the [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): +To update an object property, you can make use of [Object.assign{}](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): ```javascript -const newData = { - ...oldData, +const newData = Object.assign({}, oldData, { propertyToUpdate: newValue -}; +}); ``` -or by using [Object.assign{}](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign): +or by using the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator), a *proposed* syntax that's enabled in Create React App, Node.js and Chrome but not currently supported by all browsers. ```javascript -const newData = Object.assign({}, oldData, { +const newData = { + ...oldData, propertyToUpdate: newValue -}); +}; ``` To update a nested property such as `oldData.first.second.propertyToUpdate` you should remember to copy all of the original object's levels: From 8fad11db571731f1aa787624fc54c2c7724c3e3e Mon Sep 17 00:00:00 2001 From: Ernesto Garcia Date: Mon, 29 Jan 2018 10:14:42 -0300 Subject: [PATCH 3/3] Add intro to immutable updates page --- content/docs/immutable-updates.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/content/docs/immutable-updates.md b/content/docs/immutable-updates.md index 1d7cf29f8b0..57b75e55bb3 100644 --- a/content/docs/immutable-updates.md +++ b/content/docs/immutable-updates.md @@ -5,7 +5,17 @@ permalink: docs/immutable-updates.html layout: docs --- -To ensure immutability without performing expensive deep cloning, it is good practice to replace only the values which need updating and to reuse the rest of the original object. +## Overview + +Avoiding mutation of existing data structures is an especially useful technique, and especially in React it has significant benefits. + +A great source of trouble in application development comes from the need to track how the data changes over time, and when. Mutation of the app data (that is, its state) can lead to inconsistencies across different parts of your app that shares the same data. This in turn can lead to unpredictable behavior and bugs that are difficult to track. + +Additionally, immutable data structures make it easy and cheap to detect when data has changed. If you can use immutable data in performance-critical parts of your application it's easy to implement a fast [`shouldComponentUpdate()`](/docs/react-component.html#shouldcomponentupdate) method to significantly speed up your app. + +## Techniques + +To ensure immutability without performing expensive deep cloning, it is good practice to replace only the values which need updating and to reuse the rest of the original data structure. Below we document several techniques that you can use to this end. ### Updating Object Properties @@ -72,7 +82,7 @@ or without mutating a copy: ```javascript // inserting const newArray = [ - ...oldArray.slice(0, insertIndex), + ...oldArray.slice(0, insertIndex), newItem, ...oldArray.slice(insertIndex) ]; @@ -87,5 +97,3 @@ const newArray = [ ## Utility Libraries There are many libraries such as [Immutable.js](https://facebook.github.io/immutable-js/) and [immutability-helper](https://github.com/kolodny/immutability-helper) that make dealing with immutable data a lot easier. They provide a more concise and readable syntax to performing immutable updates and some are optimised to perform immutable updates more efficiently than the approaches above. - -