在React中动态加载Markdown文件

5

我使用markdown-to-jsx在我的React组件中呈现markdown。

我的问题是我想动态加载markdown文件,而不是使用import指定。场景是在文章详情页面上发生的,即根据路由参数获取articleId,然后基于该id加载相应的markdown文件,例如article-123.md

这是我目前的进展。如何动态加载md文件?

import React, { Component } from 'react'
import Markdown from 'markdown-to-jsx';
import articleMd from './article-123.md'

class Article extends Component {
  constructor(props) {
    super(props)
    this.state = { md: '' }
  }

  componentWillMount() {
    fetch(articleMd)
      .then((res) => res.text())
      .then((md) => {
        this.setState({ md })
      })
  }

  render() {
    return (
      <div className="article">
        <Markdown children={this.state.md}/>
      </div>
    )
  }
}

export default Article

这个代码本来是可以正常工作的,但如果我删除顶部的import articleMd from './article-123.md'并直接传递文件路径来获取它,输出的结果看起来像是index.html,而不是预期的md文件。

你好,实际的*.md文件在哪里?根据它的路径/位置,如果你移除了导入,可能它不会被包含在webpack的输出中,然后Express开发服务器将为你提供index.html。 - marcodt89
.md文件与导入它的组件位于同一目录中。明确一点,我看不到index.html,我仍然看到我的组件。但是在我的组件内,它不会呈现md文件的内容,而是呈现了一个看起来像index.html的内容,以<!DOCTYPE html>开头。 - Ben
1
我需要告诉Webpack将所有的md文件包含在输出中吗?如何实现? - Ben
1
通常,您可以在webpack.config.js中进行修改,以添加包含要包含在输出中的.md文件的路径,但如果您使用create-react-app,则无法这样做(除非您弹出它)... 在后一种情况下,您应该将md文件放置在public文件夹中。 - marcodt89
请查看以下链接以获取更多参考:https://create-react-app.dev/docs/using-the-public-folder - marcodt89
2个回答

4

你不能使用动态导入吗?

class Article extends React.Component {
    constructor(props) {
        super(props)
        this.state = { md: '' }
    }

    async componentDidMount() {
        const articleId = this.props.params.articleId; // or however you get your articleId
        const file = await import(`./article-${articleId}.md`);
        const response = await fetch(file.default);
        const text = await response.text();

        this.setState({
            md: text
        })
    }

    render() {
        return (
            <div className="article">
                <Markdown children={this.state.md} />
            </div>
        )
    }
}

动态导入是一个很好的功能,当你想要懒加载一些明确定义的 JavaScript 时,比如用 React.lazy 渲染的组件。如果它被这样使用,我猜他会遇到同样的问题... index.html 会被加载,而不是实际的 md,因为 webpack 不会将 md 包含在构建输出中。 - marcodt89
1
这段代码能够正确返回 .md 文件的内容,因为我已经测试过了。与他的代码不同之处在于使用了动态导入,其中 file.default 返回 .md 文件的相对路径,并将该部分传递给 fetch(在他的示例中,他尝试直接在 fetch 中使用 './article-123.md',而没有生成相对路径)。'file.default' 返回类似于 '/static/media/generated-string.md' 的内容。 - zhuber
我明白了,你说得对!我一直认为webpack会将*.md文件从捆绑包中排除,但实际上它并没有。不过还好,现在我知道了,谢谢。 - marcodt89

1

我知道这是一个旧的线程,但我刚刚用以下代码解决了这个问题 使用 markdown-to-jsx

import React, { Component } from 'react'
import Markdown from 'markdown-to-jsx'

    class Markdown_parser extends Component {
        
        
      constructor(props) {
        super(props)
        
        this.state = { md: "" }
      }
    
      componentWillMount() {
        const { path } = this.props;
        import(`${path}`).then((module)=>
        
        fetch(module.default)
          .then((res) => res.text())
          .then((md) => {
            this.setState({ md })
          })
        )
      }
    
      render() {
    
        let { md } = this.state
    
        return (
          <div className="post">
            <Markdown children={md} />
          </div>
        )
      }
    }
    
    export default Markdown_parser

我会翻译成中文:"

然后我按以下方式调用类

"。
<Markdown_parser path = "path-to-your-fle" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接