How do we access this.props.location in 4.x?
In 3.x routes where nested in a parent route defining the parent component, so we used to:
# routes.js =>
<Route path="/admin" component={Layout}>
<IndexRedirect to="/admin/home" />
<Route path="/admin/home" component={Home} />
# layout.js =>
<ReactCSSTransitionGroup transitionName={this.props.location.action == 'POP' ? 'slide-right': 'slide-left'} transitionEnterTimeout={500} transitionLeaveTimeout={500}>
But now how do I access this.props.location?
# routes.js
<ConnectedRouter history={history}>
<Layout>
<Switch>
<Route exact path="/" render={() => <Redirect to="/home" />} />
<Route exact path="/home" component={Home} />
Checkout the docs for Route props in v4. If you're using the Route component prop in your example above, you will get history as a prop to Home and be able to access history.location:
const Home = ({ history: { location } }) => {...}
@jayjaycross thanks for replying me!
But location prop is needed in the wrapper component which animates the route transitioning.
The example in the docs is very cryptic to me (with stateless functional components instead of ES6 classes and the giant render function).
Can you help me understand how to properly migrate?
Scenarios:
// routes.js or app.js in old 3.0
render() {
return (
<Provider store={store}>
<Router history={history}>
<Route path="/admin" component={Layout}>
<IndexRedirect to="/admin/home" />
<Route path="/admin/home" component={Home} />
<Route path="/admin/auth" component={Auth} />
<Route path="/admin/list/:entity/:filter" component={List} />
<Route path="/admin/list/:entity" component={List} />
<Route path="/admin/item/:entity/:id" component={Item} />
<Route path="/admin/item/:entity" component={Item} />
<Route path="/admin/*" component={NotFound} />
</Route>
</Router>
</Provider>
);
}
// routes.js or app.js in new 4.0
render() {
return (
<Provider store={store}>
<ConnectedRouter history={history}>
<Layout>
<Switch>
<Route exact path="/" render={() => <Redirect to="/home" />} />
<Route exact path="/home" component={Home} />
<Route exact path="/auth" component={Auth} />
<Route exact path="/calendar" component={Calendar} />
<Route exact path="/scores" component={ScoreList} />
<Route exact path="/score" component={ScoreItem} />
<Route path="*" component={NotFound} />
</Switch>
</Layout>
</ConnectedRouter>
</Provider>
);
}
//layout.js
render() {
const location = this.props.location; // this is not passed in 4.0 because layout is not a child of the route anymore!
const transition = {this.props.location.action == 'POP' ? 'slide-right' : 'slide-left'}
return (
<MuiThemeProvider muiTheme={theme}>
<div>
<ReactCSSTransitionGroup transitionName={transition} transitionEnterTimeout={2500} transitionLeaveTimeout={2500}>
<div key={location.pathname}>
{this.props.children}
</div>
</ReactCSSTransitionGroup>
</div>
</MuiThemeProvider>
);
}
Sure, so instead of <ConnectedRouter> you probably want to be using <BrowserRouter>, and you won't need to pass it a history object anymore.
Also, you can use a <Route> component pretty much anywhere to expose the history.location that you need. I would do something like this:
//layout.js
render() {
const transition = {this.props.location.action == 'POP' ? 'slide-right' : 'slide-left'};
<MuiThemeProvider muiTheme={theme}>
<div>
<Route
render={({ history: { location } }) =>
<ReactCSSTransitionGroup transitionName={transition} transitionEnterTimeout={2500} transitionLeaveTimeout={2500}>
<div key={location.pathname}>
{this.props.children}
</div>
</ReactCSSTransitionGroup>}
/>
</div>
</MuiThemeProvider>
}
@jayjaycross <BrowserRouter> is not in react-router but is in react-router-dom. The later now preferred in v4 as per https://reacttraining.com/react-router/web
My ref: https://github.com/ReactTraining/react-router/issues/4940
No, it's in react-router-dom: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js
Most helpful comment
@jayjaycross thanks for replying me!
But location prop is needed in the wrapper component which animates the route transitioning.
The example in the docs is very cryptic to me (with stateless functional components instead of ES6 classes and the giant render function).
Can you help me understand how to properly migrate?
Scenarios: