Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 788
hally9k Avatar asked Jul 05 '19 03:07

hally9k


People also ask

Does useSelector trigger re-render?

With useSelector() , returning a new object every time will always force a re-render by default. If you want to retrieve multiple values from the store, you can: Call useSelector() multiple times, with each call returning a single field value.

Can I use selector in reducer?

It's not typically possible to use selectors inside of reducers, because a slice reducer only has access to its own slice of the Redux state, and most selectors expect to be given the entire Redux root state as an argument.

How do I use useDispatch in functional component?

UseSelector and useDispatch in React Redux It takes in a function argument that returns the part of the state that you want. The equivalent of map dispatch to props is useDispatch. We can invoke useDispatch and store it to a variable, dispatch. Dispatch will work with the allActions imported from the actions folder.


1 Answers

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.

like image 68
Fyodor Avatar answered Nov 01 '22 17:11

Fyodor