问题描述
我需要动态加载反应组件.
I need to load a react component dynamically.
我从用户那里获取要作为字符串加载的组件的名称.我正在使用 webpack.
I get name of the component to load as a string from user. I'm using webpack.
如何动态加载组件而不是静态导入语句.似乎 Require.Ensure
不计算表达式.我想要达到的目标是这样的.
How do I load the component dynamically instead of having a static import statement. It seems Require.Ensure
doesn't evaluate expressions . What I want to achieve is something like this.
require.ensure([ "./widgets/" + componentName ] ,(require) => {
let Component = require("./widgets/" + componentName);
});
但这似乎不起作用.
推荐答案
基本上归结为预先创建您将需要的所有块.然后你只需要一种动态引用它们的方法.这是我基于我的解决方案:
Basically it boils down to pre-creating all the chunks you will ever need. Then you just need a way to dynamically refer to them. Here's the solution I based mine on:
http://henleyedition.com/implicit-code-splitting-with-react-router-and-webpack
这是我所做的,因为我不使用 React Router(旁注:我认为它不适合 redux 或动画):
and here's what I do since I don't use React Router (side note: i dont find it to be a good match for redux or animations):
//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 />;
}
}
所以结果是您正在动态渲染一个组件,但是来自一组静态的预先确定的可能性——同时,只发送给客户端的不是访问者实际感兴趣的块.
So the result is you are dynamically rendering a component, but from a static pre-determined set of possibilities--all while, only sending no more to the client than the chunks the visitor is actually interested in.
此外,这是我拥有的一个组件,它做得很好:
ALSO, here's a component I have that does this well:
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>
);
}
}
以this.props.requestLazybundle
的形式传递一个异步要求捆绑器函数,如下所示:
pass pass an async require bundler function as this.props.requestLazybundle
, like this:
render() {
let requestLazyBundle = require('bundle?lazy&name=AnotherComponent!../content/AnotherComponent');
return (
<AjaxModal title='Component Name' {...props} requestLazyBundle={requestLazyBundle} />
);
}
这篇关于react组件的动态加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!