サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

React入門 02: remarkableでMarkdownの機能を加える


Reactで差し込む要素のテキストを、Markdownで書いてみます。JavaScriptライブラリremarkableを使えば、MarkdownのテキストをHTMLの記述に変えることができます。また、Reactで生のHTMLを差し込む場合のやり方についてもご説明します。

01 Markdown記法とremarkableについて

Markdown」は、テキストの書式を定める簡易な記法です。HTMLコードよりも簡単な書き方で、文字や段落の表記が整えられます。そして、remarkableはMarkdownのテキストをHTMLコードに変えるJavaScriptライブラリです。「Remarkable demo」で、Markdown記法とHTMLに変換されたテキストを見比べて、試しに入力してみることもできます。

ここでは、「React入門 01: コンポーネントを組み立てる」で書いたサンプルに手を加えることにします。HTMLドキュメントには、つぎのように<script>要素でremarkableのライブラリを加えます。CDNから読み込みましたので、ダウンロードはしなくて構いません。


<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
<script src="https://npmcdn.com/react@15.3.0/dist/react.js"></script>
<script src="https://npmcdn.com/react-dom@15.3.0/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.6.2/remarkable.min.js"></script>
<script src="src/script.js" type="text/babel"></script>
</head>
<body>
	<div id="content"></div>
</body>
</html>

02 remarkableのrender()メソッドでMarkdownをHTMLの記述に変える

前出「React入門 01: コンポーネントを組み立てる」で外部JavaScriptファイルscript.jsに書いたコード003「新たにふたつ加えたコンポーネントのテキストとプロパティ値を示す」を書き替えてゆきます。まず、テキストにつぎのようにMarkdown記法を加えます。「*」(アスタリスク)と「_」(アンダースコア)は同じ働きです。それを確かめるために、あえて両方用いました。記号ひとつで文字を挟めば斜体(<em>)、ふたつなら太字(<strong>)になります。


var CommentList = React.createClass({
	render: function() {
		return (

				<Comment author="ヘンリー・キッシンジャー">チャンスは__貯金__できない。</Comment>
				<Comment author="マーク・トウェイン">禁煙なんてたやすい。私は*何千回*もやった。</Comment>

		);
	}
});

コンストラクタRemarkable()でつくったインスタンスに対してrender()メソッドを呼び出すと、引数に渡したMarkdownのテキストがHTMLの記述に変わります。なお、引数は文字列でなければならないので、toString()メソッドを加えます。そこで、コンポーネント(Comment)を、つぎのように書き直しました。ところが、Remarkableのrender()メソッドの戻り値をそのまま差し込むと、タグがテキストとして示されてしまいます(図001)。


var Comment = React.createClass({
	render: function() {
		var markDown = new Remarkable();
		return (
			<div className="comment">
				<h2 className="commentAuthor">
				{this.props.author}
				</h2>
				{markDown.render(this.props.children.toString())}
			</div>
		);
	}
});

図001■Remarkableのrender()メソッドの戻り値をそのまま差し込むとタグがテキストとして表れる

図001

03 dangerouslySetInnerHTMLプロパティによりHTMLのコードを差し込む

生のHTMLコードが差し込めてしまうと、「クロスサイトスクリプティング」(XSS)による攻撃を受けるかもしれません(「クロスサイトスクリプティング対策 ホンキのキホン」参照)。そのため、ReactはHTMLのタグは、そのままでは加えられないようにしたのです。テキストをHTMLとして差し込むためには、dangerouslySetInnerHTMLプロパティを用いなければなりません。与えるのはオブジェクトで、プロパティ__htmlにHTMLコードを値として定めます(「Dangerously Set innerHTML」参照)。

ただし、dangerouslySetInnerHTMLプロパティにオブジェクトを直に与えるのは安全といえません。別に定めたメソッドを呼び出し、その本体でオブジェクトをつくって返すのがよいでしょう。そこで、コンポーネント(Comment)はさらにつぎのように書き替えます。こうすれば、要素にはRemarkableのrender()メソッドから返されたコードが、HTMLとして描かれます(図002)。書きあがったJavaScriptファイルの中身は、以下のコード001にまとめました。また、以下のサンプル001にサイトjsdo.itのコードを掲げています。


var Comment = React.createClass({
	rawMarkup: function() {
		var markDown = new Remarkable();
		var rawMarkup = markDown.render(this.props.children.toString());
		return { __html: rawMarkup };
	},
	render: function() {
		// var markDown = new Remarkable();
		return (
			<div className="comment">
				<h2 className="commentAuthor">
				{this.props.author}
				</h2>
				<span dangerouslySetInnerHTML={this.rawMarkup()} />
			</div>
		);
	}
});

図002■Remarkableのrender()メソッドから返されたコードがHTMLとして描かれる

図002

コード001■MarkdownのテキストをHTMLのコードに変えて差し込む


var CommentBox = React.createClass({
	render: function() {
		return (
			<div className="commentBox">
				<h1>コメント</h1>
				<CommentList />
				<CommentForm />
			</div>
		);
	}
});
var CommentList = React.createClass({
	render: function() {
		return (
			<div className="commentList">
				<Comment author="ヘンリー・キッシンジャー">チャンスは__貯金__できない。</Comment>
				<Comment author="マーク・トウェイン">禁煙なんてたやすい。私は*何千回*もやった。</Comment>
			</div>
		);
	}
});
var Comment = React.createClass({
	rawMarkup: function() {
		var markDown = new Remarkable();
		var rawMarkup = markDown.render(this.props.children.toString());
		return { __html: rawMarkup };
	},
	render: function() {
		return (
			<div className="comment">
				<h2 className="commentAuthor">
				{this.props.author}
				</h2>
				<span dangerouslySetInnerHTML={this.rawMarkup()} />
			</div>
		);
	}
});
var CommentForm = React.createClass({
	render: function() {
		return (
			<div className="commentForm">
				CommentFormを表示
			</div>
		);
	}
});
ReactDOM.render(
	<CommentBox />,
	document.getElementById('content')
);

サンプル001■React: Adding Markdown


作成者: 野中文雄
更新日: 2016年8月30日 末尾のリンクにReact入門 06を追加
更新日: 2016年8月21日 末尾にReact入門シリーズのリンクを追加。
作成日: 2016年8月13日


Copyright © 2001-2016 Fumio Nonaka.  All rights reserved.