【问题标题】:Dynamically importing files into React component将文件动态导入 React 组件
【发布时间】:2020-03-02 10:42:06
【问题描述】:

我正在使用 create-react-app 和几个外部模块,例如 react-markdown。如何“要求”动态生成的文件名?我有数千个降价文件,我需要即时加载它们。如果我提供静态路径,我的组件工作正常,但当我尝试连接路径时不起作用。我无法静态导入,因为文件太多。

例子:

import React, { useState, useEffect } from "react";
import ReactMarkdown from "react-markdown/with-html"

const MarkdownServer = ({myMarkdownFilename}) => {  
  const [markdown, setValue] = useState([]);

  useEffect(() => {
    async function fetchData() {
      // this works...
      // const p = require("../../assets/markdown/mymarkdown.md") 

      // this does not.
      const p = require("../../assets/markdown/" + myMarkdownFilename);
      const markdown = await fetch(p).then(res => res.text());
      setValue(markdown);
    }
    fetchData();
  }, []);

  return (
    <p>
      <ReactMarkdown source={ markdown } escapeHtml={false} />
    </p>
  );
};

export default MarkdownServer;

错误:

Unhandled Rejection (Error): Cannot find module '../../assets/markdown/mymarkdown.md'

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    解决方案是使用Webpack context module API 创建一个上下文模块。使用一些正则表达式,我能够要求降价文档。

    在我的标准导入之后:

    const cache = {};
    
    function importAll (r) {
      r.keys().forEach(key => cache[key] = r(key));
    }
    
    importAll(require.context("../../assets/markdown/", true, /\.md$/)); 
    

    缓存对象现在包含所需的文件及其散列名称作为名称:值对。在我的代码中,我只是构建文件名并使用它来访问属性:

     useEffect(() => {
        async function fetchData() {
          filepath = "../../assets/markdown/" + myMarkdownFilename
          const p = cache[filepath]
          const markdown = await fetch(p).then(res => res.text());
          setValue(markdown);
        }
        fetchData();
      }, []);
    

    话虽如此,确实应该有一种更明智的方式来导入静态资产。

    【讨论】:

      【解决方案2】:

      您是否尝试过将 React 的 lazysuspense API 用于动态 importing

      我自己还没有使用它,但您似乎可以用类似const p = React.lazy(() =&gt; import("../../assets/markdown/" + myMarkdownFilename)); 的东西替换require(),然后让return 语句在Suspense 内渲染ReactMarkdown 组件组件。

      如果你使用 webpack,你可能还想查看here

      告诉我进展如何!

      【讨论】:

      • 延迟导入应该可以,但您不需要 Suspense。
      • 刚试过这个,连同“可加载”模块,都不管用。
      猜你喜欢
      • 2018-06-24
      • 2020-10-18
      • 1970-01-01
      • 2017-04-19
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多