4

我尝试使用react-router和webpack设置dynamic routingrequire.ensure函数加载模块,但getComponent方法不提供组件。getComponent不渲染组件

在我的示例中,Button组件默认呈现(在主页上)。当我点击按钮时,路由器将我重定向到/ admin url,并且我可以在我的Web控制台中看到require.ensure加载了新块,但未呈现Label组件。

index.jsx

import React, {Component} from 'react'; 
import ReactDOM from 'react-dom'; 
import {Router, Route, useRouterHistory, browserHistory} from 'react-router'; 
import { createHashHistory } from 'history' 
import Button from './components/button'; 

let appHistory = useRouterHistory(createHashHistory)({queryKey: false}); 

ReactDOM.render(
    <Router history={appHistory} onUpdate={() => window.scrollTo(0, 0)}> 

    <Route path="/" component={Button} > 
     <Route path="index" getComponent={(nextState, cb) => { 
      require.ensure([], function (require) { 
       cb(null, require('./components/button').default) 
      })}} 
     /> 
     <Route path="admin" getComponent={(nextState, cb) => { 
      require.ensure([], function (require) { 
       cb(null, require('./components/label').default) 
      })}} 
     /> 
    </Route> 

    </Router> 
    , document.getElementById('content') 
); 

button.jsx

var React = require('react'); 

var bootstrap = require('bootstrap'); 
var bootstrapStyle = require("bootstrap/dist/css/bootstrap.css"); 

export default class Button extends React.Component { 

    constructor(props) { 
     super(props); 

     this.onRedirect = this.onRedirect.bind(this); 
    } 

    onRedirect(){ 
    this.context.router.push({ 
       pathname: `/admin` 
      }); 
    } 

    render() { 
    return <button className="btn btn-info" type="button" onClick={this.onRedirect}> 
     <span className="glyphicon glyphicon-refresh"></span> 
    </button>; 
    } 
} 

Button.contextTypes = { 
    router: React.PropTypes.object 
}; 

label.jsx

var React = require('react'); 

var bootstrap = require('bootstrap'); 
var bootstrapStyle = require("bootstrap/dist/css/bootstrap.css"); 

export default class Label extends React.Component { 
    render() { 
    return <span className="label label-default">Default</span>; 
    } 
} 

的package.json

"dependencies": { 
    "babel": "^6.5.2", 
    "babel-core": "^6.18.0", 
    "babel-loader": "^6.2.7", 
    "babel-preset-es2015": "^6.18.0", 
    "babel-preset-react": "^6.16.0", 
    "bootstrap": "^3.3.7", 
    "css-loader": "^0.25.0", 
    "file-loader": "^0.9.0", 
    "history": "^2.0.1", 
    "html-webpack-plugin": "^2.24.1", 
    "http-server": "^0.9.0", 
    "jquery": "^3.1.1", 
    "less": "^2.7.1", 
    "less-loader": "^2.2.3", 
    "node-sass": "^3.10.1", 
    "npm-install-webpack-plugin": "^4.0.4", 
    "react": "^15.3.2", 
    "react-dom": "^15.3.2", 
    "react-router": "^3.0.0", 
    "sass-loader": "^4.0.2", 
    "style-loader": "^0.13.1", 
    "url-loader": "^0.5.7", 
    "webpack": "^1.13.3", 
    "webpack-dev-server": "^1.16.2", 
    "webpack-merge": "^0.15.0" 
    } 
+0

我不知道答案,但在这段代码中'路径名:\'/ admin \''是那些引号是否正确? – pablopunk

+1

@pablopunk反引号在ES6中是有效的字符串分隔符 - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals –

+0

您能向我们展示webpack配置吗? webpack是否为你制作了3个大块?你如何在html中包含主要的'.js'文件? – Everettss

回答

2

你的问题不是getComponent或动态路由,但你的路由配置。在导航到/admin时,react-router会匹配您的顶级路线和管理路线并相应地进行渲染:<Button><Label /></Button>。由于Button不会呈现this.props.children,因此Label也不会呈现。

通过看你的代码,也许这就是你想要的配置:你可以阅读更多关于组件如何在route configuration guideRoute API呈现

<Route path="/" component={props => <div>{props.children}</div>}> 
    <IndexRoute component={Button} /> 
    <Route path="index" /> 
    <Route path="admin" /> 
</Route> 

+0

谢谢亚历山大,它现在有效 – Matt

2

我认为你不能像require('./components/label').default飞导入您的组件。你必须导入组件:

import Label from './components/label'; 

再到代码:

cb(null, Label); 

source

+0

我试过了,但Label组件未加载。我试图实现[动态路由](https://github.com/petehunt/webpack-howto#9-async-loading) – Matt

+0

@Matt代码看起来有效。这种动态需求在webpack的chunking应用程序中很常见。看看这个代码:https://github.com/Everettss/spa-optimization/blob/stage1/src/routes.js – Everettss

+0

@Everettss感谢分享,我会试试看:)在我的情况下,我错了路由器配置 – Matt