React Router 4 + 代码拆分 |组件重新安装

React Router 4 + Code splitting | Component remounts

我有下一个代码:

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>
        )
    }
}

当状态更新时(kappa 变为真并出现 p),活动路线上的组件(无论它是什么 - IndexPageRegistration)重新安装。如果我在 App 中手动导入组件并将其传递给 Route 而无需代码拆分,则路由上的组件不会重新挂载(这很明显)。

我也试过webpack的动态导入,像这样:

<Route path="/some-path" component={props => <AsyncView {...props} component="ComponentFolderName" />

其中 import(`/path/to/${this.props.component}/index.jsx`)componentDidMount 中运行并填充 AsyncView 的状态,其行为类似于 Loadable 情况。

我想,问题是 component for Route 是一个匿名函数

问题是:如何避免重挂路由组件?

好吧,这种行为是正常的,并记录在 React Router 4 文档中:

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 在 React Loader 和 webpack 的代码拆分中都可以正常工作。