Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getters in Redux's actions - React Native

I would like to have functions that can get the current state to do some logic with it, without having to pass the current state via parameters to the function.

Here is my example.

In my action file, I have:

export const addToSearchHistory = (newSearch) => ({type: ADD_TO_SEARCH_HISTORY, newSearch})
export const addToCardHistory = (newCard) => ({type: ADD_TO_CARD_HISTORY, newCard})

And for example I would like to have a "getter" function that tells me if the "Search history" has hit 10 items. So what I did is:

export const searchHasMaxHistory = () => (dispatch, getState) => {
  var state = getState()
      search = state.search

  return search.history == 10 ? true : false
}

And I bind this function with the other "real" actions with bindActionCreators:

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({
    addToSearchHistory,
    addToCardHistory,

    searchHasMaxHistory
  }, dispatch)
} 

So I'll be accessible as any normal actions. It works well and does exactly what I want.

But the real question is, is it anti-pattern to bind it like an action but it doesn't return an action? May I run into issues or whatsoever by doing that? And is there a "right" solution to do that?

like image 426
Leon Avatar asked Nov 28 '16 13:11

Leon


People also ask

Can you use hooks in Redux actions?

React Redux offers a set of hooks as an alternative to the existing connect() higher-order component. These hooks allow you to connect to the Redux store and dispatch actions without having to wrap your components in connect().

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.

How does mapState to props work?

As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.

What is reselect and how it works?

Reselect provides a function called createSelector to generate memoized selectors. createSelector accepts one or more "input selector" functions, plus an "output selector" function, and returns a new selector function for you to use.


1 Answers

For this, you should bind your "getter" (which is described as a "selector" in the docs) to your component via the mapStateToProps function.

// the selector (probably in your reducer file)

export const searchHasMaxHistory = state => {
  return state.search.history == 10 ? true : false
}

// in your component

const mapStateToProps = (state) => {
  return {
    hasHitMaxHistory: searchHasMaxHistory(state)
  }
}

const mapDispatchToProps = ... // keep the same, remove your "getter"

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(YourComponent)

This approach makes more sense to me, as your component's new prop will behave as intended, and trigger a render() when the returned value changes.

like image 75
vgrafe Avatar answered Nov 13 '22 13:11

vgrafe