Velvet Star Monitor

Standout celebrity highlights with iconic style.

updates

How do I render Markdown from a React component?

Writer Matthew Harrington

I have my documentation written in markdown and I would like to render those files from my JSX (ES6+CommonJS) code into React components. How can I achieve this?

For example I have styles.markdown and I would like to render it into a <p> tag.

5

5 Answers

You can use React-Markdown:

const React = require('react')
const ReactDOM = require('react-dom')
const ReactMarkdown = require('react-markdown')
const input = '# This is a header\n\nAnd this is a paragraph'
ReactDOM.render(<ReactMarkdown source={input} />, document.getElementById('container'))

Or... You can just create a simple React component that wraps a call to a Markdown parser. There are two very good ones for JavaScript:

Now, you can create a component like this:

var MarkdownViewer = React.createClass({ render: function() { // pseudo code here, depends on the parser var markdown = markdown.parse(this.props.markdown); return <div dangerouslySetInnerHTML={{__html:markdown}} />; }
});

There used to have one already, but it doesn't seem to be maintained anymore:

Also, if you need a React Markdown Editor, check out: react-mde. Disclaimer: I am the author.

4

The package react-markdown with Markdown component will be good choice:

import React from 'react'
import Markdown from 'react-markdown'
var src = "# This is markdown document"
React.render( <Markdown children={src} />, document.getElementById('root')
)

You can write inplace here-docs like this:

<Markdown> # Header * dotted lists * [url](/doc)
</Markdown>

It is possible to specify transformers for link-urls and image-urls and much more.

4

Example of Markdown component that renders html from markdown text, the logic of loading data should be implemented in separate store/parent component/whatever. I am using marked package for converting markdown to html.

import React from 'react';
import marked from 'marked';
export default class MarkdownElement extends React.Component { constructor(props) { super(props); marked.setOptions({ gfm: true, tables: true, breaks: false, pedantic: false, sanitize: true, smartLists: true, smartypants: false }); } render() { const { text } = this.props, html = marked(text || ''); return (<div> <div dangerouslySetInnerHTML={{__html: html}} /> </div>); }
}
MarkdownElement.propTypes = { text: React.PropTypes.string.isRequired
};
MarkdownElement.defaultProps = { text: ''
};

I'm a little late to the party, but I wrote a competitor library to the ones mentioned above that has an added benefit of not needing the dangerouslySetInnerHtml hack:

1

Try something like this:

import fs from 'fs';
import React, { Component, PropTypes } from 'react';
class Markdown extends Component { constructor() { super(props); this.state = { contents: '' }; this.componentDidMount = this.componentDidMount.bind(this); } componentDidMount() { const contents = fs.readFileSync(this.props.path, 'utf8'); this.setState({ contents }); } render() return ( <div> {this.state.contents.split('\n').map((line, i) => line ? <p key={i}>{line}</p> : <br key={i} />)} </div> ); }
}
Markdown.propTypes = { path: PropTypes.string.isRequired };
React.render(<Markdown path='./README.md' />, document.body);

Or if you're using ES7+ features:

import fs from 'fs';
import React, { Component, PropTypes } from 'react';
class Markdown extends Component { static propTypes = { path: PropTypes.string.isRequired }; state = { contents: '' }; componentDidMount = () => { const contents = fs.readFileSync(this.props.path, 'utf8'); this.setState({ contents }); }; render() { return ( <div> {this.state.contents.split('\n').map((line, i) => line ? <p key={i}>{line}</p> : <br key={i} />)} </div> ); }
}
React.render(<Markdown path='./README.md' />, document.body);

You'll need to use the brfs transform to be able to use fs.readFileSync if this is running client-side.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy