Skip to content

Instantly share code, notes, and snippets.

@misterussell
Created April 10, 2018 01:04
Show Gist options
  • Save misterussell/3c42dd812e2358cf6843a5d4b934f660 to your computer and use it in GitHub Desktop.
Save misterussell/3c42dd812e2358cf6843a5d4b934f660 to your computer and use it in GitHub Desktop.
4 9 18 Blog Post

Roadblock, re-routing. React Router v4

This is a shallow dive into a recent roadblock I encountered with react-router v4. Routing with the previous build most routing was handled with pushing to history in props. v4 seems less direct and the new behavior seems to keep logic segmented rather than throwing 100 routes together in the index router, which I like. In this recap I will be referencing my optimization of Conway’s Game of Life. The challenge: to properly render a child route such that:

/stats/gameOfLife renders on navigation to that URL and all other components are unmounted.

Typically in prior releases I would have handled this in my routes module:

<Route path="/stats" component={ StatDash } />
<Route path="/stats/gameOfLife" component={ gameOfLifeStats }/>

In v4 this moves out of the routes module and actual into the parent component. I.E. if we want to render a child of stats, we must let stats handle that rendering. Here's how I have my initial stat component rendering:

render() {
  const stats = this.props.location.state.type === 'GOLstats'
    ? <Route path="/stats/gameOfLife" component= { GameOfLifeStats}
    : null;

  return (
    <div>
      <h1>Stats</h1>
      {
        stats
      }
    </div>
    );
}

I like this pattern. It does make more sense from a structural standpoint. Your parent must always render first to get access to the subroute. This let's the parent handle swapping around the different subroutes.

Another issue I initially ran into was how to handle routing. I'm used to using <Link /> for my initial navigation paired with pushing to history for continued navigation. Moving away from pushing to history and wrapping my navigation in another link took me some time to get to. I kept trying to reach out beyond the component to make changes.

So, using a button to navigate to a new URL now looks like:

<Link to={{
  pathname:'/stats/gameOfLife',
  state: {
    stats: this.props.stats,
    type: 'GOLstats'
  }
  }}>
  <Button />
</Link>

I find this a little more declarative. Maybe that isn't the right word. Now I can handle passing in the computed props from one component to another without having to send them to state. This may change, but initially seems like a streamlined way of passing info around while programmatically navigating.

Also, sidenote. If you want subroute navigation to work correctly, make sure you are using the subroute URL you made and not just making a new one up in the other component, because nothing new will render. Because the route does not exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment