使用getComponent的嵌套路由不会呈现

时间:2017-04-07 16:22:40

标签: reactjs react-router

我一直在构建一个具有react-router 3.x设置的React应用程序,如下所示:

<Route component={Global}>
    <Route path="/" getComponent={(loc, cb) => loadRoute('Home', cb)} />
    <Route path="/app" component={App}>
        <IndexRoute
            getComponent={(loc, cb) => loadRoute('AppHome', cb)}
        />
        <Route
            path="search"
            getComponent={(loc, cb) => loadRoute('Search', cb)}
        />
    </Route>
</Route>

我已经在App内对容器进行分块工作了。 loadRoute函数包含System.import调用添加containers/${name}/index.js

但是,向getComponent={loadRoute(...)}添加动态App并导航至/app会导致Global没有孩子;下载AppAppHome的JS块但未安装任何内容。

loadRoute功能:

const loadRoute = (container, callback) => {
    return System
        .import(`containers/${container}/index.js`)
        .then(module => callback(null, module.default))
        .catch(errorLoading);
};

1 个答案:

答案 0 :(得分:0)

对于任何看到这个问题并处于相同位置的人。几个月前我解决了这个问题。

我使用component代替getComponent并向其传递了一个组件,该组件负责异步加载块,显示加载微调器并在可用时呈现它。 react-async-component包也可以解决这个问题。

现在,分块路由可以嵌套多层深度,允许在react-router 3.x中进行真正的代码分割。

<强>组件/ AsyncComponent.js

import React from 'react';

const defaultLoadingElement = <div>Loading spinner...</div>;

const asyncComp = (getComponent, loadingElement = defaultLoadingElement) => {
  return class AsyncComponent extends React.Component {
    static Component = null;
    state = { Component: AsyncComponent.Component };

    componentWillMount() {
      if(!this.state.Component) {
        getComponent().then(Component => {
          AsyncComponent.Component = Component;
          this.setState({ Component });
        });
      }
    }

    render() {
      const { Component } = this.state;
      if(Component) {
        return <Component {...this.props} />;
      }

      return loadingElement;
    }
  };
};

export default asyncComp;

<强> routes.js

import React from 'react';
import { IndexRoute, Route } from 'react-router';

import asyncComp from 'components/AsyncComponent';

const loadRoute = container => asyncComp(() =>
  import(`containers/${container}/index.js`)
    .then(module => module.default)
);

const errorLoading = err => {
  const error = new Error();
  console.log(error.stack, err.stack);
  throw new Error(`Dynamic page loading failed: ${err}`);
};

export default store => {
  return (
    <Route path="/admin" component={loadRoute('Admin')}>
      <IndexRoute component={loadRoute('Admin/Dashboard')} />
      <Route
        path="accounts"
        component={loadRoute('Admin/Accounts')}
      />
    </Route>
  );
};