react-redux useSelector hook disallows passing props directly to the selector

13,924

This is good practice to use props in selectors.

The selector function does not receive an ownProps argument. However, props can be used through closure (see the examples below) or by using a curried selector.

useSelector accepts function with state argument. If you'll pass arrow function to useSelector you'll be able to access any variable in closure, including props.

This example is taken from official documentation

import React from 'react'
import { useSelector } from 'react-redux'

export const TodoListItem = props => {
  const todo = useSelector(state => state.todos[props.id])
  return <div>{todo.text}</div>
}

Also take a look at stale props page in official documentation on how to avoid some mistakes with local props usage.

Share:
13,924
hally9k
Author by

hally9k

Frontend Engineer with considerable experience building cool stuff in React, Redux and more recently Apollo GraphQL. Keen to jump off big things, solve problems for people, swim in the sea at unadvised times of the year and other assorted heroics. Father of three.

Updated on June 16, 2022

Comments

  • hally9k
    hally9k almost 2 years

    I've just started playing with the new useSelector hook provided in react-redux.

    I have always passed props directly in to my selectors like this:

    mapStateToProps(state, ownProps) {
       return {
          user: userSelector(state, ownProps.userId)
       }
    }
    

    Is passing props directly into selectors considered an anti pattern?

    If "No", then how can I achieve this with useSelector?

    If "Yes", then what are the correct patterns to achieve this parameterisation of the selector?

  • hally9k
    hally9k over 4 years
    thanks! If the selector is more complicated than the naive example, e.g. a selector composed of multiple other selectors etc. do I have to create a new instance, close over props and memoize it in the component's function scope? This removes reselect from stack pretty much. Hmmm. Keen to see a more real world example of a composed and memoized selector if you're game!
  • robmcm
    robmcm almost 4 years
    you can still reference a more complex selector (such as a reselect combine selector in that callback) useSelector(state => someSelector(state, {id: props.id}}