[英]Dynamic loading of react components inside state
I have a really interesting problem at hand. 我手头有一个非常有趣的问题。
I am currently working on a Admin-Interface for a headless CMS and I want to dynamically load the components for viewing the content of different parts. 我目前正在为无头CMS设计Admin-Interface,并且我想动态加载组件以查看不同部分的内容。
I know that it is rather easy to accomplish wit React Router since v4, but I don't want to rely on Routes to handle this to keep the URL as clean as possible. 我知道从v4开始使用React Router相当容易,但是我不想依靠Routes来处理它以保持URL尽可能干净。
Here is what I am trying to do: 这是我正在尝试做的事情:
async componentWillMount()
function of this basic layout I want to import()
said components using await import()
async componentWillMount()
函数内部,我想使用await import()
来import()
所述组件 this.state.mainComponents
this.state.mainComponents
的状态中。 state
state
当前显示的组件 I tried several different approaches, but did not manage to get it to work until now. 我尝试了几种不同的方法,但直到现在一直没有使它起作用。
This is what I have now: 这就是我现在所拥有的:
async componentDidMount() {
const mainComponents = {
Dashboard: await import('../_mainComponents/Dashboard').then(
({ Dashboard }) => {
return Dashboard;
},
),
};
const componentNames = [];
for (let p in mainComponents) {
componentNames.push(p);
}
this.setState({
mainComponents: {
views: mainComponents,
names: componentNames,
},
currentComponent: mainComponents.Dashboard,
currentTitle: 'Dashboard',
});
}
I would really appreciate any help you could give me on this. 我真的很感谢您可以为此提供的任何帮助。
EDIT: 编辑:
So according to the answer of @Mosè Raguzzini I implemented react-loadable
again and tried to store the const inside my state like this: 因此,根据@MosèRaguzzini的回答,我再次实现了
react-loadable
,并尝试将const存储在我的状态中,如下所示:
const LoadableDashboard = Loadable({
loader: () => import('../_mainComponents/Dashboard'),
loading: Loading
});
const mainComponents = {
Dashboard: LoadableDashboard
};
And inside my constructor function I am trying to pass this Object into the state like this: 在我的构造函数中,我试图将此对象传递给这样的状态:
const componentNames = [];
for (let p in mainComponents) {
componentNames.push(p);
}
this.state = {
mainComponents: {
views: mainComponents,
names: componentNames,
},
currentComponent: null,
currentTitle: null,
loading: false,
};
It is not working when trying to output the Components stored inside the this.state.mainComponents.views
object inside to the render function. 尝试将存储在
this.state.mainComponents.views
对象内部的组件输出到render函数时,此方法不起作用。
When using <Dashboard />
it is working as expected, but this is not what I am trying to accomplish here since I don't want to add every component to the render function in a massive switch ... case
. 当使用
<Dashboard />
它可以按预期工作,但这不是我想要在这里完成的工作,因为我不想在大量的switch ... case
中将每个组件添加到render函数中。
Does anybody of you have an idea how I can accomplish this? 你们中有人知道我该如何做到吗?
I found a solution to my problem and wanted to share it with all of those who will come after me searching for an appropiate answer. 我找到了解决问题的方法,并希望与所有寻求我找到合适答案的人分享。
Here is what I did: 这是我所做的:
import Loadable from 'react-loadable';
import Loading from '../_helperComponents/Loading';
// Define the async-loadable components here and store them inside of the mainComponent object
const LoadableDashboard = Loadable({
loader: () => import('../_mainComponents/Dashboard'),
loading: Loading,
});
const LoadableUserOverview = Loadable({
loader: () => import('../_mainComponents/UserOverview'),
loading: Loading,
});
const mainComponents = {
Dashboard: <LoadableDashboard />,
User: <LoadableUserOverview />,
};
I do not store the components inside my state (it would have been possible but goes against the guidelines as I've found out by researching state even further) :D 我没有将组件存储在我的状态内(这是可能的,但是违反了我进一步研究状态所发现的准则):D
With this object I can simply call the corresponding component by outputting it in the render()
function like this: 有了这个对象,我可以像下面这样简单地通过在
render()
函数中输出相应的组件来调用它:
render() {
return (
<div>
{mainComponents[this.state.currentComponent]}
</div>
);
}
I hope I could help someone with this. 我希望我可以帮助某人。 Happy coding!
编码愉快!
I suggest to take a look to react-loadable: 我建议看一下react-loadable:
import Loadable from 'react-loadable';
import Loading from './my-loading-component';
const LoadableComponent = Loadable({
loader: () => import('./my-component'),
loading: Loading,
});
export default class App extends React.Component {
render() {
return <LoadableComponent/>;
}
}
It provides the feature you need in a clean style. 它以简洁的样式提供您需要的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.