Skip to content

Commit a226034

Browse files
CodinCattimdorr
authored andcommitted
Prettier to faq folder (reduxjs#2391)
1 parent f878baa commit a226034

File tree

2 files changed

+74
-76
lines changed

2 files changed

+74
-76
lines changed

docs/faq/ImmutableData.md

Lines changed: 73 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Redux's use of shallow equality checking requires immutability if any connected
6363
### How do shallow and deep equality checking differ?
6464
Shallow equality checking (or _reference equality_) simply checks that two different _variables_ reference the same object; in contrast, deep equality checking (or _value equality_) must check every _value_ of two objects' properties.
6565

66-
A shallow equality check is therefore as simple (and as fast) as `a === b`, whereas a deep equality check involves a recursive traversal through the properties of two objects, comparing the value of each property at each step.
66+
A shallow equality check is therefore as simple (and as fast) as `a === b`, whereas a deep equality check involves a recursive traversal through the properties of two objects, comparing the value of each property at each step.
6767

6868
It's for this improvement in performance that Redux uses shallow equality checking.
6969

@@ -90,8 +90,8 @@ The [suggested structure](http://redux.js.org/docs/faq/Reducers.html#reducers-sh
9090
`combineReducers` makes working with this style of structure easier by taking a `reducers` argument that’s defined as a hash table comprising a set of key/value pairs, where each key is the name of a state slice, and the corresponding value is the reducer function that will act on it.
9191

9292
So, for example, if your state shape is `{ todos, counter }`, the call to `combineReducers` would be:
93-
```
94-
combineReducers({ todos: myTodosReducer, counter: myCounterReducer })
93+
```js
94+
combineReducers({ todos: myTodosReducer, counter: myCounterReducer })
9595
```
9696

9797
where:
@@ -105,7 +105,7 @@ where:
105105

106106
As it continues through the iterations, `combineReducers` will construct a new state object with the state slices returned from each reducer. This new state object may or may not be different from the current state object. It is here that `combineReducers` uses shallow equality checking to determine whether the state has changed.
107107

108-
Specifically, at each stage of the iteration, `combineReducers` performs a shallow equality check on the current state slice and the state slice returned from the reducer. If the reducer returns a new object, the shallow equality check will fail, and `combineReducers` will set a `hasChanged` flag to true.
108+
Specifically, at each stage of the iteration, `combineReducers` performs a shallow equality check on the current state slice and the state slice returned from the reducer. If the reducer returns a new object, the shallow equality check will fail, and `combineReducers` will set a `hasChanged` flag to true.
109109

110110
After the iterations have completed, `combineReducers` will check the state of the `hasChanged` flag. If it’s true, the newly-constructed state object will be returned. If it’s false, the _current_ state object is returned.
111111

@@ -148,20 +148,20 @@ React-Redux performs a shallow equality check on on each _value_ within the prop
148148

149149
It does so because the props object is actually a hash of prop names and their values (or selector functions that are used to retrieve or generate the values), such as in this example:
150150

151-
```
151+
```js
152152
function mapStateToProps(state) {
153-
return {
154-
todos: state.todos, // prop value
155-
visibleTodos: getVisibleTodos(state) // selector
156-
}
153+
return {
154+
todos: state.todos, // prop value
155+
visibleTodos: getVisibleTodos(state) // selector
156+
}
157157
}
158158

159159
export default connect(mapStateToProps)(TodoApp)
160160
```
161161

162162
As such, a shallow equality check of the props object returned from repeated calls to `mapStateToProps` would always fail, as a new object would be returned each time.
163163

164-
React-Redux therefore maintains separate references to each _value_ in the returned props object.
164+
React-Redux therefore maintains separate references to each _value_ in the returned props object.
165165

166166
#### Further Information
167167

@@ -173,35 +173,35 @@ React-Redux therefore maintains separate references to each _value_ in the retur
173173
### How does React-Redux use shallow equality checking to determine whether a component needs re-rendering?
174174
Each time React-Redux’s `connect` function is called, it will perform a shallow equality check on its stored reference to the root state object, and the current root state object passed to it from the store. If the check passes, the root state object has not been updated, and so there is no need to re-render the component, or even call `mapStateToProps`.
175175

176-
If the check fails, however, the root state object _has_ been updated, and so `connect` will call `mapStateToProps`to see if the props for the wrapped component have been updated.
176+
If the check fails, however, the root state object _has_ been updated, and so `connect` will call `mapStateToProps`to see if the props for the wrapped component have been updated.
177177

178178
It does this by performing a shallow equality check on each value within the object individually, and will only trigger a re-render if one of those checks fails.
179179

180180
In the example below, if `state.todos` and the value returned from `getVisibleTodos()` do not change on successive calls to `connect`, then the component will not re-render .
181181

182-
```
182+
```js
183183
function mapStateToProps(state) {
184-
return {
185-
todos: state.todos, // prop value
186-
visibleTodos: getVisibleTodos(state) // selector
187-
}
184+
return {
185+
todos: state.todos, // prop value
186+
visibleTodos: getVisibleTodos(state) // selector
187+
}
188188
}
189189

190190
export default connect(mapStateToProps)(TodoApp)
191191
```
192192

193193
Conversely, in this next example (below), the component will _always_ re-render, as the value of `todos` is always a new object, regardless of whether or not its values change:
194194

195-
```
195+
```js
196196
// AVOID - will always cause a re-render
197197
function mapStateToProps(state) {
198-
return {
199-
// todos always references a newly-created object
200-
todos: {
201-
all: state.todos,
202-
visibleTodos: getVisibleTodos(state)
203-
}
204-
}
198+
return {
199+
// todos always references a newly-created object
200+
todos: {
201+
all: state.todos,
202+
visibleTodos: getVisibleTodos(state)
203+
}
204+
}
205205
}
206206

207207
export default connect(mapStateToProps)(TodoApp)
@@ -228,16 +228,16 @@ Shallow equality checking cannot be used to detect if a function mutates an obje
228228
This is because two variables that reference the same object will _always_ be equal, regardless of whether the object’s values changes or not, as they're both referencing the same object. Thus, the following will always return true:
229229

230230

231-
```
231+
```js
232232
function mutateObj(obj) {
233-
obj.key = 'newValue';
234-
return obj;
233+
obj.key = 'newValue'
234+
return obj
235235
}
236236

237-
const param = { key: 'originalValue' };
238-
const returnVal = mutateObj(param);
237+
const param = { key: 'originalValue' }
238+
const returnVal = mutateObj(param)
239239

240-
param === returnVal;
240+
param === returnVal
241241
//> true
242242
```
243243

@@ -254,7 +254,7 @@ The shallow check of `param` and `returnValue` simply checks whether both variab
254254
### Does shallow equality checking with a mutable object cause problems with Redux?
255255
Shallow equality checking with a mutable object will not cause problems with Redux, but [it will cause problems with libraries that depend on the store, such as React-Redux](#shallow-checking-problems-with-react-redux).
256256

257-
Specifically, if the state slice passed to a reducer by `combineReducers` is a mutable object, the reducer can modify it directly and return it.
257+
Specifically, if the state slice passed to a reducer by `combineReducers` is a mutable object, the reducer can modify it directly and return it.
258258

259259
If it does, the shallow equality check that `combineReducers` performs will always pass, as the values of the state slice returned by the reducer may have been mutated, but the object itself has not - it’s still the same object that was passed to the reducer.
260260

@@ -289,37 +289,35 @@ As we’ve seen, the values in the mutable object returned by the selector funct
289289

290290
For example, the following `mapStateToProps` function will never trigger a re-render:
291291

292-
```
292+
```js
293293
// State object held in the Redux store
294294
const state = {
295-
user: {
296-
accessCount: 0,
297-
name: 'keith'
298-
}
299-
};
295+
user: {
296+
accessCount: 0,
297+
name: 'keith'
298+
}
299+
}
300300

301301
// Selector function
302-
const getUser = (state) => {
303-
++state.user.accessCount; // mutate the state object
304-
return state;
302+
const getUser = state => {
303+
++state.user.accessCount // mutate the state object
304+
return state
305305
}
306306

307307
// mapStateToProps
308-
const mapStateToProps = (state) => ({
309-
// The object returned from getUser() is always
310-
// the same object, so this wrapped
311-
// component will never re-render, even though it's been
312-
// mutated
313-
userRecord: getUser(state)
314-
});
315-
308+
const mapStateToProps = state => ({
309+
// The object returned from getUser() is always
310+
// the same object, so this wrapped
311+
// component will never re-render, even though it's been
312+
// mutated
313+
userRecord: getUser(state)
314+
})
316315

317-
const a = mapStateToProps(state);
318-
const b = mapStateToProps(state);
316+
const a = mapStateToProps(state)
317+
const b = mapStateToProps(state)
319318

320-
a.userRecord === b.userRecord;
319+
a.userRecord === b.userRecord
321320
//> true
322-
323321
```
324322

325323
Note that, conversely, if an _immutable_ object is used, the [component may re-render when it should not](#immutability-issues-with-react-redux).
@@ -335,7 +333,7 @@ Note that, conversely, if an _immutable_ object is used, the [component may re-r
335333

336334
<a id="immutability-enables-shallow-checking"></a>
337335
### How does immutability enable a shallow check to detect object mutations?
338-
If an object is immutable, any changes that need to be made to it within a function must be made to a _copy_ of the object.
336+
If an object is immutable, any changes that need to be made to it within a function must be made to a _copy_ of the object.
339337

340338
This mutated copy is a _separate_ object from that passed into the function, and so when it is returned, a shallow check will identify it as being a different object from that passed in, and so will fail.
341339

@@ -366,17 +364,17 @@ To prevent this from happening, you must *always return the state slice object t
366364
### How can immutability in `mapStateToProps` cause components to render unnecessarily?
367365
Certain immutable operations, such as an Array filter, will always return a new object, even if the values themselves have not changed.
368366

369-
If such an operation is used as a selector function in `mapStateToProps`, the shallow equality check that React-Redux performs on each value
367+
If such an operation is used as a selector function in `mapStateToProps`, the shallow equality check that React-Redux performs on each value
370368
in the props object that’s returned will always fail, as the selector is returning a new object each time.
371369

372-
As such, even though the values of that new object have not changed, the wrapped component will always be re-rendered,
370+
As such, even though the values of that new object have not changed, the wrapped component will always be re-rendered,
373371

374372
For example, the following will always trigger a re-render:
375373

376-
```
374+
```js
377375
// A JavaScript array's 'filter' method treats the array as immutable,
378376
// and returns a filtered copy of the array.
379-
const getVisibleTodos = (todos) => todos.filter(t => !t.completed);
377+
const getVisibleTodos = todos => todos.filter(t => !t.completed)
380378

381379
const state = {
382380
todos: [
@@ -385,31 +383,31 @@ const state = {
385383
completed: false
386384
},
387385
{
388-
text: 'do todo 2',
386+
text: 'do todo 2',
389387
completed: true
390-
}]
388+
}
389+
]
391390
}
392-
393-
394-
const mapStateToProps = (state) => ({
395-
// getVisibleTodos() always returns a new array, and so the
396-
// 'visibleToDos' prop will always reference a different array,
397-
// causing the wrapped component to re-render, even if the array's
398-
// values haven't changed
399-
visibleToDos: getVisibleTodos(state.todos)
391+
392+
const mapStateToProps = state => ({
393+
// getVisibleTodos() always returns a new array, and so the
394+
// 'visibleToDos' prop will always reference a different array,
395+
// causing the wrapped component to re-render, even if the array's
396+
// values haven't changed
397+
visibleToDos: getVisibleTodos(state.todos)
400398
})
401399

402-
const a = mapStateToProps(state);
400+
const a = mapStateToProps(state)
403401
// Call mapStateToProps(state) again with exactly the same arguments
404-
const b = mapStateToProps(state);
402+
const b = mapStateToProps(state)
405403

406-
a.visibleToDos;
404+
a.visibleToDos
407405
//> { "completed": false, "text": "do todo 1" }
408406

409-
b.visibleToDos;
407+
b.visibleToDos
410408
//> { "completed": false, "text": "do todo 1" }
411409

412-
a.visibleToDos === b.visibleToDos;
410+
a.visibleToDos === b.visibleToDos
413411
//> false
414412
```
415413

@@ -425,8 +423,8 @@ Note that, conversely, if the values in your props object refer to mutable objec
425423

426424

427425
<a id="do-i-have-to-use-immutable-js"></a>
428-
## What approaches are there for handling data immutably? Do I have to use Immutable.JS?
429-
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.
426+
## What approaches are there for handling data immutably? Do I have to use Immutable.JS?
427+
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.
430428

431429
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.
432430

@@ -442,7 +440,7 @@ However, guaranteeing immutability with JavaScript is difficult, and it can be e
442440
JavaScript was never designed to provide guaranteed immutable operations. Accordingly, there are several issues you need to be aware of if you choose to use it for your immutable operations in your Redux app.
443441

444442
### Accidental Object Mutation
445-
With JavaScript, you can accidentally mutate an object (such as the Redux state tree) quite easily without realising it. For example, updating deeply nested properties, creating a new *reference* to an object instead of a new object, or performing a shallow copy rather than a deep copy, can all lead to inadvertent object mutations, and can trip up even the most experienced JavaScript coder.
443+
With JavaScript, you can accidentally mutate an object (such as the Redux state tree) quite easily without realising it. For example, updating deeply nested properties, creating a new *reference* to an object instead of a new object, or performing a shallow copy rather than a deep copy, can all lead to inadvertent object mutations, and can trip up even the most experienced JavaScript coder.
446444

447445
To avoid these issues, ensure you follow the recommended [immutable update patterns for ES6](http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html).
448446

docs/faq/ReactRedux.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Note that “updating data immutably” does *not* mean that you must use [Immut
5151
React Redux implements several optimizations to ensure your actual component only re-renders when actually necessary. One of those is a shallow equality check on the combined props object generated by the `mapStateToProps` and `mapDispatchToProps` arguments passed to `connect`. Unfortunately, shallow equality does not help in cases where new array or object instances are created each time `mapStateToProps` is called. A typical example might be mapping over an array of IDs and returning the matching object references, such as:
5252

5353
```js
54-
const mapStateToProps = (state) => {
54+
const mapStateToProps = state => {
5555
return {
5656
objects: state.objectIds.map(id => state.objects[id])
5757
}

0 commit comments

Comments
 (0)