Tom Fenech Tom Fenech - 2 months ago 12
React JSX Question

Access react router state in selector

I am moving a part of my app's state from the store to the URL.

I am currently using redux to manage my app's state along with reselect to create selectors. The selectors compute derived values from the state in the redux store (in principal, this is their only input).

Now part of the state will be contained within the URL instead, so I'm not sure how to go about reading it.

I have looked at react-router-redux, which at first glance may appear to be the solution (indeed, I can get to the value I want using

state.routing.locationBeforeTransitions.query
) but this doesn't seem to be the right way to do it, given that in their docs it says:


You should not read the location state directly from the Redux store.


Is there another way that I can access my location state, or should I just ignore this warning and use it in my selector?

Answer

You are correct that the react-router-redux docs seem to recommend against getting your router state this way.

While Reselect selectors commonly only make use of the first argument (the state), they can actually take a second argument (the component's props). Inside these props you will find the params being passed by React Router (assuming they are being passed to the component you are trying to connect).

I have included a trivial example below where all I'm doing is upper-casing the location, but you can imagine making as complex a selector as you want that includes other selectors that use state to get things out of the Redux store.

const selectLocation = (_state, props) => props.location;
const selector = createSelector(
  selectLocation, 
  (location) => ({ upperCasedLocation: location.toUpperCase() })
);

const MySmartComponent = (props) => <div>{props.upperCasedLocation}</div>;

export default connect(selector)(MySmartComponent);