Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically loading Markdown file in React

I use markdown-to-jsx to render markdown in my React component.

My problem is that I want to dynamically load the markdown file, instead of specifying it with import. The scenario is that this happens on an article details page, i.e. I get the articleId from the route params and then based on that id, I want to load the corresponding markdown file, e.g. article-123.md.

Here's what I have so far. How can I load the md file dynamically?

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

This works fine as is, but if I remove import articleMd from './article-123.md' at the top and instead pass the file path directly to fetch it output what looks like index.html, not the expected md file.

like image 452
Ben Avatar asked Aug 26 '19 08:08

Ben


2 Answers

Can't you use dynamic import?

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>
        )
    }
}
like image 70
zhuber Avatar answered Oct 19 '22 16:10

zhuber


I know this is an old thread but I just solved this issue with the following code using 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

I then call the class sa follows

<Markdown_parser path = "path-to-your-fle" />
like image 23
Emiliano Penaloza Avatar answered Oct 19 '22 16:10

Emiliano Penaloza