Skip to content

Commit 0640501

Browse files
MrWolfZtimdorr
authored andcommitted
Various adjustments to hooks docs (#1293)
* fix bug in useActions recipe in the hooks docs * various adjustments to hooks docs * correct a statement about preventing stale props
1 parent 8a645be commit 0640501

File tree

1 file changed

+8
-26
lines changed

1 file changed

+8
-26
lines changed

docs/api/hooks.md

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@ export const TodoCounterForIsDoneValue = ({ isDone }) => {
194194
[]
195195
)
196196

197-
const NumOfTodosWithIsDoneValue = useSelector(state =>
197+
const numOfTodosWithIsDoneValue = useSelector(state =>
198198
selectNumOfTodosWithIsDoneValue(state, isDone)
199199
)
200200

201-
return <div>{NumOfTodosWithIsDoneValue}</div>
201+
return <div>{numOfTodosWithIsDoneValue}</div>
202202
}
203203

204204
export const App = () => {
@@ -340,45 +340,27 @@ If you prefer to deal with this issue yourself, here are some possible options f
340340

341341
- Don't rely on props in your selector function for extracting data
342342
- In cases where you do rely on props in your selector function _and_ those props may change over time, _or_ the data you're extracting may be based on items that can be deleted, try writing the selector functions defensively. Don't just reach straight into `state.todos[props.id].name` - read `state.todos[props.id]` first, and verify that it exists before trying to read `todo.name`.
343-
- Because `connect` adds the necessary `Subscription` to the context provider, wrapping the component with `connect` (without any arguments, i.e. `connect()(MyComponent)` will keep those issues from occurring.
343+
- Because `connect` adds the necessary `Subscription` to the context provider and delays evaluating child subscriptions until the connected component has re-rendered, putting a connected component in the component tree just above the component using `useSelector` will prevent these issues as long as the connected component gets re-rendered due to the same store update as the hooks component.
344344

345345
> **Note**: For a longer description of this issue, see [this chat log that describes the problems in more detail](https://gist.github.com/markerikson/faac6ae4aca7b82a058e13216a7888ec), as well as [issue #1179](https://github.com/reduxjs/react-redux/issues/1179).
346346
347347
### Performance
348348

349-
As mentioned earlier, `useSelector()` will do basic shallow comparisons of return values when running the selector function after an action is dispatched. However, unlike `connect()`, `useSelector()` does not do anything to prevent your own function component from completing a re-render if the derived state has changed.
349+
As mentioned earlier, by default `useSelector()` will do a reference equality comparison of the selected value when running the selector function after an action is dispatched, and will only cause the component to re-render if the selected value changed. However, unlike `connect()`, `useSelector()` does not prevent the component from re-rendering due to its parent re-rendering, even if the component's props did not change.
350350

351-
If further performance optimizations are necessary, you may consider either wrapping your function component in `React.memo(MyFunctionComponent)`, or using `useMemo()` to memoize the render output of your component:
351+
If further performance optimizations are necessary, you may consider wrapping your function component in `React.memo()`:
352352

353353
```jsx
354-
// Option 1: use React.memo() to keep the component from re-rendering
355-
356-
const CounterComponent = props => {
354+
const CounterComponent = ({ name }) => {
357355
const counter = useSelector(state => state.counter)
358356
return (
359357
<div>
360-
{props.name}: {counter}
358+
{name}: {counter}
361359
</div>
362360
)
363361
}
364362

365363
export const MemoizedCounterComponent = React.memo(CounterComponent)
366-
367-
// Option 2: let the component re-render, but memoize output
368-
369-
export const CounterComponent = props => {
370-
const counter = useSelector(state => state.counter)
371-
372-
const renderedChildren = useMemo(() => {
373-
return (
374-
<div>
375-
{props.name}: {counter}
376-
</div>
377-
)
378-
}, [props.name, counter])
379-
380-
return renderedChildren
381-
}
382364
```
383365

384366
## Hooks Recipes
@@ -401,7 +383,7 @@ export function useActions(actions, deps) {
401383
return actions.map(a => bindActionCreators(a, dispatch))
402384
}
403385
return bindActionCreators(actions, dispatch)
404-
}, deps)
386+
}, deps ? [dispatch, ...deps] : deps)
405387
}
406388
```
407389

0 commit comments

Comments
 (0)