Skip to content

Commit

Permalink
Merge pull request reduxjs#4053 from AaronPowell96/master
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Apr 1, 2021
2 parents 182266e + 347a2ef commit 2e9a2d4
Show file tree
Hide file tree
Showing 13 changed files with 19 additions and 482 deletions.
8 changes: 1 addition & 7 deletions docs/FAQ.md
Expand Up @@ -34,14 +34,8 @@ hide_title: true
- **Immutable Data**
- [What are the benefits of immutability?](faq/ImmutableData.md#what-are-the-benefits-of-immutability)
- [Why is immutability required by Redux?](faq/ImmutableData.md#why-is-immutability-required-by-redux)
- [What approaches are there for handling data immutability? Do I have to use Immutable.JS?](faq/ImmutableData.md#what-approaches-are-there-for-handling-data-immutability-do-i-have-to-use-immutable-js)
- [What approaches are there for handling data immutability? Do I have to use Immer?](faq/ImmutableData.md#what-approaches-are-there-for-handling-data-immutability-do-i-have-to-use-immer)
- [What are the issues with using JavaScript for immutable operations?](faq/ImmutableData.md#what-are-the-issues-with-using-plain-javascript-for-immutable-operations)
- **Using Immutable.JS with Redux**
- [Why should I use an immutable-focused library such as Immutable.JS?](recipes/UsingImmutableJS.md#why-should-i-use-an-immutable-focused-library-such-as-immutable-js)
- [Why should I choose Immutable.JS as an immutable library?](recipes/UsingImmutableJS.md#why-should-i-choose-immutable-js-as-an-immutable-library)
- [What are the issues with using Immutable.JS?](recipes/UsingImmutableJS.md#what-are-the-issues-with-using-immutable-js)
- [Is Immutable.JS worth the effort?](recipes/UsingImmutableJS.md#is-using-immutable-js-worth-the-effort)
- [What are some opinionated Best Practices for using Immutable.JS with Redux?](recipes/UsingImmutableJS.md#what-are-some-opinionated-best-practices-for-using-immutable-js-with-redux)
- **Code Structure**
- [What should my file structure look like? How should I group my action creators and reducers in my project? Where should my selectors go?](faq/CodeStructure.md#what-should-my-file-structure-look-like-how-should-i-group-my-action-creators-and-reducers-in-my-project-where-should-my-selectors-go)
- [How should I split my logic between reducers and action creators? Where should my “business logic” go?](faq/CodeStructure.md#how-should-i-split-my-logic-between-reducers-and-action-creators-where-should-my-business-logic-go)
Expand Down
2 changes: 1 addition & 1 deletion docs/api/createStore.md
Expand Up @@ -50,7 +50,7 @@ console.log(store.getState())

- Don't create more than one store in an application! Instead, use [`combineReducers`](combineReducers.md) to create a single root reducer out of many.

- It is up to you to choose the state format. You can use plain objects or something like [Immutable](https://facebook.github.io/immutable-js/). If you're not sure, start with plain objects.
- Redux state is normally plain JS objects and arrays.

- If your state is a plain object, make sure you never mutate it! For example, instead of returning something like `Object.assign(state, newData)` from your reducers, return `Object.assign({}, state, newData)`. This way you don't override the previous `state`. You can also write `return { ...state, ...newData }` if you enable the [object spread operator proposal](../recipes/UsingObjectSpreadOperator.md).

Expand Down
19 changes: 7 additions & 12 deletions docs/faq/ImmutableData.md
Expand Up @@ -23,7 +23,7 @@ hide_title: true
- [How does immutability enable a shallow check to detect object mutations?](#how-does-immutability-enable-a-shallow-check-to-detect-object-mutations)
- [How can immutability in your reducers cause components to render unnecessarily?](#how-can-immutability-in-your-reducers-cause-components-to-render-unnecessarily)
- [How can immutability in mapStateToProps cause components to render unnecessarily?](#how-can-immutability-in-mapstatetoprops-cause-components-to-render-unnecessarily)
- [What approaches are there for handling data immutability? Do I have to use Immutable.JS?](#what-approaches-are-there-for-handling-data-immutability-do-i-have-to-use-immutable-js)
- [What approaches are there for handling data immutability? Do I have to use Immer?](#what-approaches-are-there-for-handling-data-immutability-do-i-have-to-use-immer)
- [What are the issues with using JavaScript for immutable operations?](#what-are-the-issues-with-using-plain-javascript-for-immutable-operations)

## What are the benefits of immutability?
Expand All @@ -36,9 +36,8 @@ In particular, immutability in the context of a Web app enables sophisticated ch

**Articles**

- [Introduction to Immutable.js and Functional Programming Concepts](https://auth0.com/blog/intro-to-immutable-js/)
- [Introduction to Immer](https://immerjs.github.io/immer/)
- [JavaScript Immutability presentation (PDF - see slide 12 for benefits)](https://www.jfokus.se/jfokus16/preso/JavaScript-Immutability--Dont-Go-Changing.pdf)
- [Immutable.js - Immutable Collections for JavaScript](https://facebook.github.io/immutable-js/#the-case-for-immutability)
- [React: Optimizing Performance](https://facebook.github.io/react/docs/optimizing-performance.html)
- [JavaScript Application Architecture On The Road To 2015](https://medium.com/google-developers/javascript-application-architecture-on-the-road-to-2015-d8125811101b#.djje0rfys)

Expand Down Expand Up @@ -431,18 +430,18 @@ Note that, conversely, if the values in your props object refer to mutable objec
- [Building Efficient UI with React and Redux](https://www.toptal.com/react/react-redux-and-immutablejs)
- [ImmutableJS: worth the price?](https://medium.com/@AlexFaunt/immutablejs-worth-the-price-66391b8742d4#.a3alci2g8)

## What approaches are there for handling data immutability? Do I have to use Immutable.JS?
## What approaches are there for handling data immutability? Do I have to use Immer?

You do not need to use Immutable.JS with Redux. Plain JavaScript, if written correctly, is perfectly capable of providing immutability without having to use an immutable-focused library.
You do not need to use Immer with Redux. Plain JavaScript, if written correctly, is perfectly capable of providing immutability without having to use an immutable-focused library.

However, guaranteeing immutability with JavaScript is difficult, and it can be easy to mutate an object accidentally, causing bugs in your app that are extremely difficult to locate. For this reason, using an immutable update utility library such as Immutable.JS can significantly improve the reliability of your app, and make your app’s development much easier.
However, guaranteeing immutability with JavaScript is difficult, and it can be easy to mutate an object accidentally, causing bugs in your app that are extremely difficult to locate. For this reason, using an immutable update utility library such as Immer can significantly improve the reliability of your app, and make your app’s development much easier.

#### Further Information

**Discussions**

- [#1185: Question: Should I use immutable data structures?](https://github.com/reduxjs/redux/issues/1422)
- [Introduction to Immutable.js and Functional Programming Concepts](https://auth0.com/blog/intro-to-immutable-js/)
- [Introduction to Immer](https://immerjs.github.io/immer/)

## What are the issues with using plain JavaScript for immutable operations?

Expand All @@ -464,9 +463,7 @@ Operating on JavaScript objects and arrays in an immutable way can be slow, part

Remember, to change an immutable object, you must mutate a _copy_ of it, and copying large objects can be slow as every property must be copied.

In contrast, immutable libraries such as Immutable.JS can employ sophisticated optimization techniques such as [structural sharing](https://www.slideshare.net/mohitthatte/a-deep-dive-into-clojures-data-structures-euroclojure-2015) , which effectively returns a new object that reuses much of the existing object being copied from.

For copying very large objects, [plain JavaScript can be over 100 times slower](https://medium.com/@dtinth/immutable-js-persistent-data-structures-and-structural-sharing-6d163fbd73d2#.z1g1ofrsi) than an optimized immutable library.
In contrast, immutable libraries such as Immer can employ structural sharing, which effectively returns a new object that reuses much of the existing object being copied from.

#### Further Information

Expand All @@ -476,9 +473,7 @@ For copying very large objects, [plain JavaScript can be over 100 times slower](

**Articles**

- [Immutable.js, persistent data structures and structural sharing](https://medium.com/@dtinth/immutable-js-persistent-data-structures-and-structural-sharing-6d163fbd73d2#.a2jimoiaf)
- [A deep dive into Clojure’s data structures](https://www.slideshare.net/mohitthatte/a-deep-dive-into-clojures-data-structures-euroclojure-2015)
- [Introduction to Immutable.js and Functional Programming Concepts](https://auth0.com/blog/intro-to-immutable-js/)
- [JavaScript and Immutability](https://t4d.io/javascript-and-immutability/)
- [Immutable Javascript using ES6 and beyond](https://wecodetheweb.com/2016/02/12/immutable-javascript-using-es6-and-beyond/)
- [Pros and Cons of using immutability with React.js - React Kung Fu](https://reactkungfu.com/2015/08/pros-and-cons-of-using-immutability-with-react-js/)
2 changes: 1 addition & 1 deletion docs/faq/ReactRedux.md
Expand Up @@ -54,7 +54,7 @@ Accidentally mutating or modifying your state directly is by far the most common

It's important to remember that whenever you update a nested value, you must also return new copies of anything above it in your state tree. If you have `state.a.b.c.d`, and you want to make an update to `d`, you would also need to return new copies of `c`, `b`, `a`, and `state`. This [state tree mutation diagram](http://arqex.com/wp-content/uploads/2015/02/trees.png) demonstrates how a change deep in a tree requires changes all the way up.

Note that “updating data immutably” does _not_ mean that you must use [Immutable.js](https://facebook.github.io/immutable-js/), although that is certainly an option. You can do immutable updates to plain JS objects and arrays using several different approaches:
Note that “updating data immutably” does _not_ mean that you must use [Immer](https://github.com/immerjs/immer), although that is certainly an option. You can do immutable updates to plain JS objects and arrays using several different approaches:

- Copying objects using functions like `Object.assign()` or `_.extend()`, and array functions such as `slice()` and `concat()`
- The array spread operator in ES6, and the similar object spread operator that is proposed for a future version of JavaScript
Expand Down
84 changes: 1 addition & 83 deletions docs/introduction/Ecosystem.md
Expand Up @@ -303,45 +303,7 @@ store.dispatch({
## Immutable Data
#### Data Structures
**[facebook/immutable-js](https://github.com/facebook/immutable-js)** <br />
Immutable persistent data collections for Javascript
```js
const map1 = Map({ a: 1, b: 2, c: 3 })
const map2 = map1.set('b', 50)
map1.get('b') // 2
map2.get('b') // 50
```
**[rtfeldman/seamless-immutable](https://github.com/rtfeldman/seamless-immutable)** <br />
Frozen immutable arrays/objects, backwards-compatible with JS
```js
const array = Immutable(['totally', 'immutable', { a: 42 }])
array[0] = 'edited' // does nothing
```
**[planttheidea/crio](https://github.com/planttheidea/crio)** <br />
Immutable JS objects with a natural API
```js
const foo = crio(['foo'])
const fooBar = foo.push('bar') // new array: ['foo', 'bar']
```
**[aearly/icepick](https://github.com/aearly/icepick)** <br />
Utilities for treating frozen JS objects as persistent immutable collections.
```js
const newObj = icepick.assocIn({ c: { d: 'bar' } }, ['c', 'd'], 'baz')
const obj3 = icepicke.merge(obj1, obj2)
```
#### Immutable Update Utilities
**[mweststrate/immer](https://github.com/mweststrate/immer)** <br />
**[ImmerJS/immer](https://github.com/immerjs/immer)** <br />
Immutable updates with normal mutative code, using Proxies
```js
Expand All @@ -351,50 +313,6 @@ const nextState = produce(baseState, draftState => {
})
```
**[kolodny/immutability-helper](https://github.com/kolodny/immutability-helper)** <br />
A drop-in replacement for react-addons-update
```js
const newData = update(myData, {
x: { y: { z: { $set: 7 } } },
a: { b: { $push: [9] } }
})
```
**[mariocasciaro/object-path-immutable](https://github.com/mariocasciaro/object-path-immutable)** <br />
Simpler alternative to immutability-helpers and Immutable.js
```js
const newObj = immutable(obj).set('a.b', 'f').del(['a', 'c', 0]).value()
```
**[debitoor/dot-prop-immutable](https://github.com/debitoor/dot-prop-immutable)** <br />
Immutable version of the dot-prop lib, with some extensions
```js
const newState = dotProp.set(state, `todos.${index}.complete`, true)
const endOfArray = dotProp.get(obj, 'foo.$end')
```
#### Immutable/Redux Interop
**[gajus/redux-immutable](https://github.com/gajus/redux-immutable)** <br />
combineReducers equivalent that works with Immutable.js Maps
```js
const initialState = Immutable.Map()
const rootReducer = combineReducers({})
const store = createStore(rootReducer, initialState)
```
**[eadmundo/redux-seamless-immutable](https://github.com/eadmundo/redux-seamless-immutable)** <br />
combineReducers equivalent that works with seamless-immutable values
```js
import { combineReducers } from 'redux-seamless-immutable';
const rootReducer = combineReducers({ userReducer, posts
```
## Side Effects
#### Widely Used
Expand Down
1 change: 0 additions & 1 deletion docs/recipes/README.md
Expand Up @@ -18,7 +18,6 @@ These are some use cases and code snippets to get you started with Redux in a re
- [Computing Derived Data](ComputingDerivedData.md)
- [Implementing Undo History](ImplementingUndoHistory.md)
- [Isolating Redux Sub-Apps](IsolatingSubapps.md)
- [Using Immutable.JS with Redux](UsingImmutableJS.md)
- [Code Splitting](CodeSplitting.md)
- [Troubleshooting](Troubleshooting.md)
- [Structuring Reducers](structuring-reducers/StructuringReducers.md)
2 changes: 1 addition & 1 deletion docs/recipes/Troubleshooting.md
Expand Up @@ -17,7 +17,7 @@ Sometimes, you are trying to dispatch an action, but your view does not update.

It is tempting to modify the `state` or `action` passed to you by Redux. Don't do this!

Redux assumes that you never mutate the objects it gives to you in the reducer. **Every single time, you must return the new state object.** Even if you don't use a library like [Immutable](https://facebook.github.io/immutable-js/), you need to completely avoid mutation.
Redux assumes that you never mutate the objects it gives to you in the reducer. **Every single time, you must return the new state object.** Even if you don't use a library like [Immer](https://github.com/immerjs/immer), you need to completely avoid mutation.

Immutability is what lets [react-redux](https://github.com/gaearon/react-redux) efficiently subscribe to fine-grained updates of your state. It also enables great developer experience features such as time travel with [redux-devtools](https://github.com/reduxjs/redux-devtools).

Expand Down

0 comments on commit 2e9a2d4

Please sign in to comment.