I have the next code:
import React from 'react'
import Loadable from 'react-loadable'
import { Route } from 'react-router-dom'
class App extends React.Component {
state = {
kappa: false
}
componentDidMount() {
setTimeout(() => {
setState({ kappa: true })
}, 1000)
}
render() {
return (
<div className="app">
<Route exact path="/:locale/" component={Loadable({
loader: () => import('../views/IndexPage/index.jsx'),
loading: () => "loading"
})} />
<Route exact path="/:locale/registration" component={Loadable({
loader: () => import('../views/Registration/index.jsx'),
loading: () => "loading"
})} />
{this.state.kappa && <p>Hey, Kappa-Kappa, hey, Kappa-Kappa, hey!</p>}
</div>
)
}
}
When state updates (kappa
becomes true and p
appears), component on active route (no matter what is it - IndexPage
or Registration
) remounts. If I import component manually in App and pass it to the Route
without code-splitting, components on routes doesn't remount (that's so obvious).
I also tried webpack's dynamic import, like this:
<Route path="/some-path" component={props => <AsyncView {...props} component="ComponentFolderName" />
where import(`/path/to/${this.props.component}/index.jsx`)
runs in componentDidMount
and upfills AsyncView
's state, and it behaves simillar to Loadable
situation.
I suppose, the problem is that component
for Route
is an anonymous function
The question is: how to avoid remount of route components?
Well, this behaviour is normal and documented at React Router 4 docs:
When you use component (instead of render or children, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop (below).
render
works fine both with React Loader and webpack's code splitting.