【发布时间】:2019-12-22 02:15:22
【问题描述】:
我一直在尝试模块化我的 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 中。
然后,在 Google 和此处进行了大量研究并找到了这个答案:React - Dynamically Import Components
使用该函数,我能够遍历清单,找到目录中的文件夹,并通过运行我在 pluginStore 中创建的 mountPlugins() 函数将插件安装在 this.state 中,在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 存储库,其中包含最少的文件集来重现该问题。
【问题讨论】:
-
你在使用动态导入
import()吗?它返回一个解析为对象的承诺。如果您使用export default MyComponent导出,它将解析为对象{ default: MyComponent }。 -
@RamilAmparo,我在 componentDidMount() 方法中使用动态导入。在动态导入中,我正在运行一个名为“mountPlugins”的函数,它将它们添加到
this.state。组件默认导出。 -
我们可以看看
pluginStore.getAll().registered.plugins正在返回什么。它可能没有返回有效的组件。 -
@RamilAmparo 用截图更新了问题。 :)
-
不要发布部分代码和屏幕截图,请附上 mwe:stackoverflow.com/help/minimal-reproducible-example。一个 github repo 将是理想的,即使它被剥离为没有任何样式的纯组件。
标签: javascript reactjs react-router modularization