我一直在尝试模块化我的 React.js 应用程序(将作为桌面应用程序与 Electron 一起交付),如果我将来制作一个新模块,我可以添加一个新文件夹并修改一个几个文件,它应该可以很好地集成。我最初受到这篇文章的启发:https ://www.nylas.com/blog/react-plugins/
在那之后,我开始尽可能多地进行研究,并最终创建了一个 JSON 文件,该文件将存在于服务器中,其中包含为该特定客户端注册的插件清单。像这样的东西:
{
"plugins": [
{
"name": "Test Plugin",
"version": "0.0.1",
"path": "testplugin",
"file": "test",
"component":"TestPlugin"
},
{
"name": "Another Plugin",
"version": "0.0.1",
"path": "anothertest",
"file": "othertest",
"component":"TestPluginDeux"
}
]
}
之后,我创建了几个与path
值匹配的文件夹,其中包含与清单中的名称匹配的组件(例如testplugin/test.jsx
,将组件导出TestPlugin
为默认值)。我还制作了一个pluginStore
文件来读取清单并将插件安装在this.state
.
然后,在谷歌和这里做了大量的研究并找到了这个答案:React - Dynamically Import Components
使用该函数,我能够遍历清单,在目录中找到文件夹,并this.state
通过运行我在主页中的方法中mountPlugins()
创建的函数将插件安装在 中。pluginStore
componentDidMount()
到现在为止还挺好。我正在使用 React-Router,我能够在 State 中动态安装插件,并能够通过像这样调用它们来将它们加载到我的 Home Route 中<TestPlugin />
:
component
我现在遇到的问题是,我想通过使用或方法动态地创建将从状态加载这些组件的路由render
,但我没有运气。我总是会得到相同的结果......显然我传递的是一个对象而不是一个字符串。
这是我这次尝试的最后一次迭代:
{this.state.modules.registered.map((item) =>
<Route exact path={`/${item.path}`} render={function() {
return <item.component />
}}></Route>
)}
之后,我创建了一个调用PluginShell
组件的路由,该组件由Navlink
发送插件名称的组件调用以动态注入和加载它。
<Route exact path='/ex/:component' component={PluginShell}></Route>
但我最终遇到了同样的问题。我正在传递一个object
并且createElement
函数需要一个string
.
我搜索了整个 StackOverflow,发现了许多类似的问题和答案。我尝试应用所有可能的解决方案,但没有成功。
编辑:我整理了一个 GitHub 存储库,其中包含最少的文件集来重现该问题。