我需要动态加载React组件。
我从用户获取要加载为字符串的组件名称。我正在使用 webpack 。
如何动态加载组件,而不要使用静态import语句。似乎Require.Ensure不评估表达式。我想要实现的是这样的事情。
Require.Ensure
require.ensure([ "./widgets/" + componentName ] ,(require) => { let Component = require("./widgets/" + componentName); });
但这似乎不起作用。
基本上,它可以归结为预先创建您将需要的所有块。然后,您只需要一种动态引用它们的方法。这是我基于的解决方案:
http://henleyedition.com/implicit-code-splitting-with-react-router-and- webpack
这是我不使用React Router的方法(注意:我发现它与redux或动画没有很好的匹配):
//loader: { test: (folder)\/.*\.js, include: path.resolve(__dirname, 'src') loader: ['lazy?bundle', 'babel'] } //dynamic usage within React component: const My_COMPONENTS = { ComponentA: require('./folder/ComponentA'), ComponentB: require('./folder/ComponentB'), } class ParentComponent extends React.Component { componentDidMount() { My_COMPONENTS[this.props.name](component => this.setState({component})); } render() { return <this.state.component />; } }
因此,结果是您正在动态渲染组件,但是是从一组静态的预先确定的可能性中进行的-同时,仅向客户端发送的内容不多于访问者实际感兴趣的部分。
另外,这是我做得很好的一个组件:
import React from 'react'; import Modal from './widgets/Modal'; export default class AjaxModal extends React.Component { constructor(props, context) { super(props, context); this.state = { Content: null }; } componentDidMount() { if(this.props.show) { this.loadContent(); } } componentWillReceiveProps({show}) { if(show && !this.state.Content) { this.loadContent(1200); //dont interfere with animation } } loadContent(ms=0) { setTimeout(() => { this.props.requestLazyBundle(({default: Content}) => { this.setState({Content}); }); }, ms); } render() { let {Content} = this.state; return ( <Modal title={this.props.title} {...this.props} loading={!Content}> {Content ? <Content /> : null} </Modal> ); } }
通过传递async require bundler函数this.props.requestLazybundle,如下所示:
this.props.requestLazybundle
render() { let requestLazyBundle = require('bundle?lazy&name=AnotherComponent!../content/AnotherComponent'); return ( <AjaxModal title='Component Name' {...props} requestLazyBundle={requestLazyBundle} /> ); }