【问题标题】:Load (external) components dynamically into React.js将(外部)组件动态加载到 React.js
【发布时间】:2016-11-09 10:01:49
【问题描述】:

所以情况 - 我想创建将利用 React 和用户\第 3 方构建的组件(小部件)的应用程序\框架。我目前的观点是,我将拥有一个 Root 组件,该组件将列出已加载的 3rd 方组件。像这样:

class Root {
 constructor(p){
  this.state = {loadedWidgets: [<Chat/>, <Mail/>, <Notes/>]}
 }
 render(){
  return(
   <div>
    <Header/>
    <Body>
     {this.state.loadedWidgets.map(WidgetName => <WidgetName />)}
    </Body>
   </div>
  )
 }
}

但我遇到了两个我无法理解或无法解决的主要问题:

  1. 如果我不应该将这些小部件硬编码到根组件中,我将如何加载(导入)它们? (我想我可以做一些钩子,以便在用户安装小部件后,它会以某种方式添加到状态和页面)
  2. 为什么 React 不以这种方式渲染真实组件:

(代码标签正常工作的列表结束)

 render(){
  const NameOfACustomComponent = this.state.loadedWidgets[0]
  return(<div><NameOfACustomComponent/></div>
 }

渲染后它将是一个自定义的 DOM 标签,而不是现有的 React 组件。

我想要构建的是 chrome 的扩展,用用户经常使用的小部件\应用程序替换新页面,同时让开发人员可以使用纯 React.js 以足够简单的方式添加新的小部件和一些用于集成的钩子。

编辑。根据this issueReact 找到第二个问题的答案,如果您引用了它的类或函数(ES5 React 风格),则允许制作任意组件。因此,对于第 2 和第 1 个问题的解决方案之一是在窗口对象中有一些注册表,其中任何组件都可以自行添加并可供框架使用。虽然它应该以严格的类实例方式完成,以提供一种方法来添加\删除仅 Widget 本身而不是它们的整个列表。

【问题讨论】:

  • 第三方组件是用 React 做的吗?

标签: javascript reactjs frameworks


【解决方案1】:

你快到了,改变

{this.state.loadedWidgets.map(WidgetName => <WidgetName />)}

{this.state.loadedWidgets.map(Widget => Widget)}

或者可能也应该工作:

{this.state.loadedWidgets}

【讨论】:

  • 是的,在阅读了编辑中提到的问题后,我明白我必须引用所有组件,但首先我想了一些神奇的方法让 React 通过它们的名称来了解所有组件。现在我明白了它只能操作知道它应该使用的组件。
【解决方案2】:

抱歉,我无法早点发布完整的解决方案。

动态组件加载的主要问题首先是提醒主渲染器组件添加或删除了某些 DC(动态组件)的方法。第二个较小,可以通过处理组件操作的对象解决第一个问题来轻松修复,因此任何 DC 都可以添加自身,并且该对象 (RDCL) 将提醒任何订阅者。 示例 RDCL 可能如下所示:

class RDCL extends Array { //so we could use filtering and stuff
  subscribe(componentType, callback) { // handle the way to notify subscriber when C. with corerct type added to RDCL }
  unsubscribe(componentType = ALL, callback) { // remove subscription }
  add(componentClassOrFunctionDefinition, [typeGoesHere?]) { // add component with default or provided or included type }
  remove(componentClassOrFunctionDefinition) { // remove component }
}

尽管使用动态第三方组件会产生另一个问题 - 如何在不包含 react 和所有已包含在主 app\framework 中的库的情况下处理捆绑。对于这个,我仍然没有答案,除了使用带有 type/babel 的普通脚本

如果您不需要第三方组件但想在应用程序的任何位置动态加载它们,那么有一个简单(可能非常脏)的解决方案:

window.ReactComponentRegistry = {}; // somewhere in root component

// some component that should be loaded dynamicaly (somewhat)
class SomeComponent exteds Component { // ... };
window.ReactComponentRegistry['SomeComponentName'] = SomeComponent;

//render() of view that would use that dynamic component
const ArbitraryComponent = window.ReactComponentRegistry.SomeComponentName // ['SomeComponentName'] obviously will work too
return(<ArbitraryComponent props={this.props} />);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-27
    • 2018-01-12
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多