React: HTML not rendering correctly

I have this React component whose main goal is to render an article stored ad MarkDown (.md file) after it is transformed into HTML by marked.

Articles.js

import React from 'react';
import marked from 'marked';
import './articles.css';

export default class Articles extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      articles: [],
      last_article: ""
    }
  }

  componentWillMount() {
    fetch('/last_article', {
      headers: {
        'Accept': 'text/markdown'
      }
    })
    .then(res => res.text())
    .then(txt => marked(txt))
    .then(html => {
      this.setState({
        last_article: html
      });
    });
  }

  render() {
    return (
      <div className="articles">
        {this.state.last_article}
      </div>
    );
  }

}

The back-end works fine and componentWillMount fetches the correct text and transforms it perfectly. But it renders like this:

enter image description here

I am not a React expert and never faced this problem before.

Any suggestions?

Upvotes: 0

Views: 3732

Answers (2)

Forrest Collins
Forrest Collins

Reputation: 79

As others have said, dangerouslySetInnerHTML will work, but if you are going to find yourself doing this a lot, check out this cool lib.

Upvotes: 1

Anurag Singh Bisht
Anurag Singh Bisht

Reputation: 2753

Use the dangerouslySetInnerHTML approach as I have described below.

Go through this link to see the proper documentation about dangerouslySetInnerHTML and it's side effects

class Articles extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      articles: [],
      last_article: ""
    }
  }

  componentWillMount() {
      this.setState({
        last_article: `<h1>Hello</h1>`
      });
    
  }
  
  getMarkdownText() {
    return { __html: this.state.last_article };
  }

  render() {
    return (
      <div className="articles" dangerouslySetInnerHTML={this.getMarkdownText()}/> 
      );
  }

}

ReactDOM.render(
  <Articles />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

Upvotes: 5

Related Questions