Skip to content

Commit d4f09a7

Browse files
authored
Add selector deps, perf info, and bump version (reduxjs#1253)
1 parent aefc520 commit d4f09a7

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

docs/api/hooks.md

+43-5
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ From there, you may import any of the listed React Redux hooks APIs and use them
3333
## `useSelector()`
3434

3535
```js
36-
const result : any = useSelector(selector : Function)
36+
const result : any = useSelector(selector : Function, deps : any[])
3737
```
3838

3939
Allows you to extract data from the Redux store state, using a selector function.
@@ -43,6 +43,7 @@ The selector is approximately equivalent to the [`mapStateToProps` argument to `
4343
However, there are some differences between the selectors passed to `useSelector()` and a `mapState` function:
4444

4545
- The selector may return any value as a result, not just an object. The return value of the selector will be used as the return value of the `useSelector()` hook.
46+
- The selector function used will be based on the `deps` array. If no deps array is provided, the latest passed-in selector function will be used when the component renders, and also when any actions are dispatched before the next render. If a deps array is provided, the last saved selector will be used, and that selector will be overwritten whenever the deps array contents have changed.
4647
- When an action is dispatched, `useSelector()` will do a shallow comparison of the previous selector result value and the current result value. If they are different, the component will be forced to re-render. If they are the same, they component will not re-render.
4748
- The selector function does _not_ receive an `ownProps` argument. If you wish to use props within the selector function to determine what values to extract, you should call the React [`useMemo()`](https://reactjs.org/docs/hooks-reference.html#usememo) or [`useCallback()`](https://reactjs.org/docs/hooks-reference.html#usecallback) hooks yourself to create a version of the selector that will be re-created whenever the props it depends on change.
4849

@@ -70,10 +71,10 @@ Using props to determine what to extract:
7071
import React, { useCallback } from 'react'
7172
import { useSelector } from 'react-redux'
7273

73-
export const TodoListItem = props => {
74-
const todoSelector = useCallback(() => {
75-
return state => state.todos[props.id]
76-
}, [props.id])
74+
export const TodoListItem = props => (
75+
state => state.todos[props.id],
76+
[props.id]
77+
)
7778

7879
const todo = useSelector(todoSelector)
7980

@@ -301,3 +302,40 @@ Some options for avoiding this problem:
301302
- Try using the single function or array forms of `useActions()`
302303

303304
> **Note**: for more details on this problem, see [this comment and following in issue #1179](https://github.com/reduxjs/react-redux/issues/1179#issuecomment-482473235), as well as [this codesandbox that demonstrates the issue](https://codesandbox.io/s/7yjn3m9n96).
305+
306+
### Performance
307+
308+
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.
309+
310+
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:
311+
312+
```jsx
313+
// Option 1: use React.memo() to keep the component from re-rendering
314+
315+
const CounterComponent = props => {
316+
const counter = useSelector(state => state.counter)
317+
return (
318+
<div>
319+
{props.name}: {counter}
320+
</div>
321+
)
322+
}
323+
324+
export const MemoizedCounterComponent = React.memo(CounterComponent)
325+
326+
// Option 2: let the component re-render, but memoize output
327+
328+
export const CounterComponent = props => {
329+
const counter = useSelector(state => state.counter)
330+
331+
const renderedChildren = useMemo(() => {
332+
return (
333+
<div>
334+
{props.name}: {counter}
335+
</div>
336+
)
337+
}, [props.name, counter])
338+
339+
return renderedChildren
340+
}
341+
```

website/siteConfig.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const siteConfig = {
108108
* After that, 7.x will no longer appear in "pre-release" versions and we should remove this line
109109
* More info: https://docusaurus.io/docs/en/versioning
110110
*/
111-
nextVersion: '7.1.0-alpha.0',
111+
nextVersion: '7.1.0-alpha.1',
112112

113113
gaTrackingId: 'UA-130598673-2'
114114
}

0 commit comments

Comments
 (0)