dipole_moment dipole_moment - 17 days ago 9
React JSX Question

Handling view logic in redux

I find that my

mapStateToProps
is increasing in complexity.

For example, across multiple connected components, I have been doing something like this:

const mapStateToProps = (state) => {
return {
activeAsset: state.assets.byId[state.assets.activeAssetId].attributes
}
}


Problem #1:
It is fairly obvious that the above code could be guarded with some conditionals since
activeAssetId
is not always set which will lead to the above throwing an error.

Problem #2:
Suppose I wanted to get the current
activeAsset
in multiple components I now have to duplicate the code above.

I have heard of reselect but I am not entirely sure if this is the correct choice here since it seems to be used specifically with memoized functions.

Please excuse me if the answer is fairly obvious, I am fairly new to the redux ecosystem.

Answer

The safe solution is to use a selector. Selectors are reusable functions that know the shape of the state in the store, and can produce derived data.

In your case, this can be your selector:

const getAssetAttributes = ({ assets }) =>  (assets.byId[state.assets.activeAssetId] && assets.byId[state.assets.activeAssetId].attributes) || null; // if the asset exists and has attributes return it, if not return null

Usage:

const mapStateToProps = (state) => {
  return {
    activeAsset: getAssetAttributes(state)
  }
}

You can create selectors for every derived data, and store them in the relevant reducer's file, or in a seperate selectors file. Reselect can help you with creating memoized standard selectors, but it's not required. Reselect selectors will returned the same data, if the parameters haven't changed, and this will prevent rerendering components needlessly.