【问题标题】:react router 4 nested components not working properly反应路由器4嵌套组件无法正常工作
【发布时间】:2017-10-13 21:21:52
【问题描述】:

我正在从 react-router 3.x 切换到 4.x,但无法渲染嵌套路由。

我使用 create-react-app 引导了一个应用程序

index.js file

import React from 'react';
import ReactDOM from 'react-dom';
import Routes from './routes';
import './index.css';

ReactDOM.render(<Routes />, document.getElementById('root'));

routes.js file

import React from 'react';
import _ from 'lodash';
import {
  BrowserRouter as Router,
  Route,
} from 'react-router-dom';
import { dojoRequire } from 'esri-loader';
import EsriLoader from 'esri-loader-react';

import App from './components/App';
import Home from './components/Home';

/**
 * Helper component to wrap app
 */
class AppWrapper extends React.Component {
  /**
   * Util function to render the children
   * Whenever a state change happens in react application, react will render the component again
   * and we wish to pass the updated state to the children as props
   */
  renderChildren() {
    const {children} = this.props;
    if (!children) {
      return;
    }

    return React.Children.map(children, c => React.cloneElement(c, _.omit(this.props, 'children'), { }));
  }

  render() {
    const child = this.renderChildren();
    return (
      <App {...this.props}>
        {child}
      </App>
    );
  }
}

/**
 * Root Loader component to load esri api
 */
class LoaderComponent extends React.Component {

  constructor(props) {
    super(props);
    this.state = { loaded: false };
  }

  /**
   * Callback fired when arc GIS api is loaded
   * Now load the requirejs modules using dojorequire
   */
  esriReady() {
    dojoRequire(['esri/Map', 'esri/views/MapView'], (Map, MapView) => {
      this.setState({ Map, MapView, loaded: true });
    });
  }

  render() {
    const options = {
      url: 'https://js.arcgis.com/4.3/',
    };
    return (
      <div>
        <EsriLoader options={options} ready={this.esriReady.bind(this)} />
        <AppWrapper {...this.state}>
          <Route exact path="/home" component={Home} />
        </AppWrapper>
      </div>
    );
  }
};

const Routes = (props) => (
  <Router {...props}>
    <Route exact path="/" component={LoaderComponent} />
  </Router>
);

export default Routes;

App 和 home 组件是呈现 &lt;div&gt;Hello world App&lt;/div&gt;&lt;div&gt;Hello world Home&lt;/div&gt; 的简单 div 标签

App 组件完美呈现,但是当我导航到 http://localhost:3000/home 组件时,我看到一个空白页面。

我想做的是

当用户启动应用程序时,用户应该被重定向到/home,我想为App 组件定义两个额外的路由

<Route exact path="/a" component={A} />
<Route exact path="/b" component={B} />

目前我无法在应用加载时重定向到/home,也无法为App 组件定义嵌套路由。

注意:上面的代码在 react-router 3.x 版本中运行良好。要在页面加载时重定向,我会使用 IndexRedirect

我已经查看了thisthis 问题,并尝试了这些问题的所有可能解决方案,但没有一个有效。

我想在routes.js 文件中处理所有路由

【问题讨论】:

    标签: javascript reactjs react-router react-router-v4


    【解决方案1】:

    您可以使用SwitchRedirect 实现这样的路由:

    import React from 'react';
    import {Route, Switch, Redirect} from 'react-router-dom';
    
    import {LoaderComponent, AppWrapper , Home, A, B} from './mycomponents';
    
    
    const routes = (
      <LoaderComponent>
        <AppWrapper>
          <Switch>
            <Route exact path='/' render={() => <Redirect to='/home' />} />
            <Route exact path='/home' component={Home} />
            <Route exact path='/a' component={A} />
            <Route exact path='/b' component={B} />
          </Switch>
        </AppWrapper>
      </LoaderComponent>
    );
    
    export default routes;
    

    并使用routes.js 文件,如下所示:

    import React from 'react';
    import {render} from 'react-dom';
    import {Router} from 'react-router-dom';
    import createHistory from 'history/createBrowserHistory';
    
    import routes from './routes';
    
    
    const history = createHistory();
    
    const App = () =>
      <Router history={history}>
        {routes}
      </Router>;
    
    render(<App />, document.getElementById('root'));
    

    【讨论】:

    • 您错过了LoaderComponent。这是必需的,因为我必须加载一些外部 api。
    • Home、A、B 这三个组件都应该遵循层次结构。 LoaderComponent -&gt; App -&gt; Home/A/B
    • 我用层次结构更新了我的答案。由于 react-router-4 中的所有内容都是一个组件,因此您可以在任何地方定义路由,而不仅仅是在 1 个文件 (routes.js) 中,如果这不是您可以组织代码的结构。
    【解决方案2】:

    嘿,我已经为一个简单的示例项目实现了react-router-v4。这是 github 链接: How to Implement the react-router-v4。请通过它。很简单。

    运行:克隆它并点击npm install。希望这对你有帮助。

    【讨论】:

      猜你喜欢
      • 2020-08-26
      • 2017-11-09
      • 2019-06-17
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2013-09-22
      相关资源
      最近更新 更多