Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Redux, Selectors, and Access to State

DZone's Guide to

Redux, Selectors, and Access to State

Check out a bit about Jamie's struggle in working out best practices for React/Redux.

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

There are a couple of things I’ve struggled a lot with in working out best practices for React/Redux:

These two things are related because selectors in general need access to the whole state tree (I think).

So I use three basic techniques:

  1. To pass state to react components, I use react-redux, where the mapStateToProps function has access to the global state.

  2. To provide state to reducers, I use redux-thunk, which lets me use state-aware action creators and thereby add all required state to the action payloads.

  3. Alternatively, I use the third argument to redux-react’s connect() function, mergeProps, which lets me access both global state and component properties and pass them to action creators (and through actions, to the reducers).

Here’s a very basic sketch of how these three approaches look:

// A redux-thunk action creator that uses the getState()
// function to pass state to selectors
export function actionCreator1(someState, someProps) {
return function (dispatch, getState) {
someMoreState = selector3(getState());

dispatch(action1(someState, someMoreState));
};
}

// A normal action creator that just gets precalculated state
export actionCreator2 = (someState) => ({
someState,
});

// A redux-react function that can use global state tree to call selectors
const mapStateToProps = (state, ownProps) => ({
state1: selector1(state),
state2: selector2(state),
});

const mapDispatchToProps = (dispatch) => ({ dispatch });

const mergeProps = (stateProps, dispatchProps, ownProps) => {
return {
...ownProps,
...stateProps,
// using stateProps to pass state to action creators
action1: () => dispatch(actionCreator1(stateProps.state1, ownProps)),
action2: () => dispatch(actionCreator2(stateProps.state2)),
}
};

export const Container = connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps
)(Component);

Using these approaches, I can get access to whatever state I need, and therefore use selectors all over the place. I suspect this also lets me get away with a pretty suboptimal state tree and just paper over the gaps with global state and heavy-weight selectors. But I suspect that even with a great state tree shape and great selector design, these techniques are still going to be necessary. Maybe just less so.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
design ,best practices ,global state ,web dev

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}