簡體   English   中英

在 React 中使用 @loadable/component 從外部腳本加載 function

[英]Load function from external script using @loadable/component in React

我有一個 JSON 文件,其中包含多個腳本文件路徑,我希望能夠動態加載到我的 React 應用程序中,以根據元數據中的規范構建每個組件。 目前,我的應用程序中有元數據作為Metadata數據數據 object。

元數據.json:

{
  "component1": { "script": "./createFirstLayer.js" },
  "component2": { "script": "./createSecondLayer.js" }
}

每個腳本都導出一個 function,我希望能夠使用它來構建組件。 出於故障排除的目的,它目前只返回一條簡單的消息。

function createFirstLayer(name) {
  return name + " loaded!";
}

export default createFirstLayer;

我做了一些研究並確定了@loadable/component package。 使用此 package 作為import loadable from "@loadable/component"; ,我試圖將我的腳本加載到 App.js 中,如下所示:

  async componentDidMount() {
    Object.keys(Metadata).forEach(function(name) {
      console.log(Metadata[name].script);
      var createLayer = loadable(() => import(Metadata[name].script));
      var message = createLayer(name);
      console.log(message);
    });
  }

我嘗試過的一切都會拋出 TypeError createLayer is not a function 如何加載 function?

我也嘗試過惰性方法。

我在這里重新創建了我的問題的工作演示。

編輯:我試圖把它放在我的應用程序的頂部

const scripts = {};
Object.keys(Metadata).forEach(async function(name) {
    import(Metadata[name].script).then((cb) => scripts[name] = cb);
});

這會導致 TypeError 未處理拒絕(錯誤):找不到模塊 './createFirstLayer.js'。 (匿名函數) src/components lazy /^.*$/ groupOptions: {} namespace object:66

我也嘗試過

const scripts = {};
Object.keys(Metadata).forEach(async function(name) {
    React.lazy(() => import(Metadata[name].script).then((cb) => scripts[name] = cb));
});

我的目標是能夠調用適當的 function 來創建特定層,並在元數據中匹配它們。

您不需要@loadable/component有兩個原因。

  1. 您可以通過動態導入來實現您的目標
  2. '@loadable/component' 返回一個 React 組件 object,而不是你的 function。

要使用動態導入,只需按照您原來的方式解析您的 JSON,但將對導入的默認 function 的調用推送到state中。 然后您所要做的就是從 state 中渲染“”。

像這樣:

import React, { Component } from "react";
import Metadata from "./metadata.json";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { messages: [] };
  }
  async componentDidMount() {
    Object.keys(Metadata).forEach(name=> import(`${Metadata[name].script}`).then(cb =>
      this.setState((state, props) => ({ messages: [...state.messages, cb.default(cb.default.name)] }))));
  }
  render() {
    return (
      <div className="App">
        {this.state.messages.map((m, idx) => (
          <h1 key={idx}>{m}</h1>
        ))}
      </div>
    );
  }
}

export default App;

這是工作示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM