Search code examples
reactjsreact-routerurl-routingquery-stringreact-router-redux

Where should I parse a Query String in ReactRouter <Route> to pass parsed values into its render method as props to another Component


I would like to render a Component using a <Route> and pass some props down to the Component that it renders. I would like these props to originate from a query string, but I am struggling to figure out the proper location to actually parse the query.

Let's say I have the following URL:

localhost:3000/privateRegistration?fullName=JohnBaker&accessKey=a4141sbgfsd

I'm also using React-Router-Redux, this is what my routerReducer looks like at this address:

const routerReducer = {
    location: {
        hash: "",
        pathname: "/privateRegistration",
        search: "?fullName=JohnBaker&accessKey=a4141sbgfsd",
    }
}

Since React-Router V4 does not natively parse query strings, I will use the node queryString module (https://www.npmjs.com/package/querystring)

const querystring = require('querystring')
const {location} = state.routerReducer

render() {
    return (
        <Route path='/privateRegistration' render={ () => {

            const parsed = querystring.parse(location.search)

            return (
               <PrivateComponent
                fullName={parsed.fullName}
                accessKey={parsed.accessKey}
               />)}
        }/>
    )
}

Is there somewhere else that I should be performing the actual parse operation other than within the <Route> render prop/method? Technically I have access to the history object outside of the context of Route, but if I moved away from Redux, where else would I access this?

I could also simply pass in the entire location.search as a prop, or more simply access it within the component through the redux store without passing props at all

I am trying to see best practices but it seems there is a debate about the best way to do this here : https://github.com/ReactTraining/react-router/issues/4410


Solution

  • Within the render function of the Route you have access to pretty much everything. You can just pass those to your PrivateComponent:

    render() {
      return (
        <Route path='/privateRegistration' render={ props => 
            <PrivateComponent { ...props } />    // ^ HERE
        } />
      )
    

    The props includes history, location and match objects with which you can do anything.