React-router: Deprecate/remove withRouter?

Created on 16 Jul 2017  路  4Comments  路  Source: ReactTraining/react-router

I'm trying to think of anything you can do using withRouter that you can't just do with a <Route render>, but I'm coming up short. I mean, just look at the implementation for goodness sake. It's implemented using <Route render>!

Would it be too much to ask people to replace all their uses of withRouter with <Route render>?

Most helpful comment

The biggest problem is going to be how people use it to wrap Redux-connected components. This is the common way we have people solve the blocked updates issue:

export default withRouter(connect(...)(MyComponent))

Wrapping that with a <Route> outside of the connect is going to involve a lot of extra boilerplate:

const ConnectedComponent = connect(...)(MyComponent)
const withRouterComponent = props => <Route render={routeProps => <ConnectedComponent {...routeProps} {...props}/>}/>
export default withRouterComponent

I'm pretty sure that's going to rustle some jimmies right off of React Router entirely...

I'd vote to leave it in. It's a very convenient boilerplate reducer.

All 4 comments

One thing that you can be sure of is that it would get a lot of complaints. In the update blocking article I tried to not mention withRouter until the very end to encourage people to pass the location prop/use <Route> and almost everywhere I have seen people just use withRouter.

The current withRouter implementation is optimized for simplicity, but could easily be rewritten to grab the values off of context and inject them. Not that it is a major optimization, but that would save rendering an extra component.

const withRouter(Component) => {
  const C = (props, context) {
    return <Component {...props} {...context} />
  }
  C.contextTypes = {...}
}

There has actually been a bug in pathless <Route render> (and thus withRouter) since release that can happen due to the current implementation. If you use either inside of a <Route children> that doesn't match, <Route render> sets the match prop to a default value when it should actually be null.) #4704.

The biggest problem is going to be how people use it to wrap Redux-connected components. This is the common way we have people solve the blocked updates issue:

export default withRouter(connect(...)(MyComponent))

Wrapping that with a <Route> outside of the connect is going to involve a lot of extra boilerplate:

const ConnectedComponent = connect(...)(MyComponent)
const withRouterComponent = props => <Route render={routeProps => <ConnectedComponent {...routeProps} {...props}/>}/>
export default withRouterComponent

I'm pretty sure that's going to rustle some jimmies right off of React Router entirely...

I'd vote to leave it in. It's a very convenient boilerplate reducer.

Ya, you guys both bring up good points. I just need to be reminded about this from time to time. I do think it's interesting how one library using HOCs tends to bleed out across the ecosystem.

@mjackson Might be worth another consideration once #5908

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yormi picture yormi  路  3Comments

misterwilliam picture misterwilliam  路  3Comments

nicolashery picture nicolashery  路  3Comments

ackvf picture ackvf  路  3Comments

jzimmek picture jzimmek  路  3Comments