Reactでマークダウンエディタをシャッとつくる

こんにちは。イノベーター・ジャパン(以下、IJ)のエンジニアのbmfです。

この記事はイノベーター・ジャパンAdvent Calendar 2017の8日目の記事です。 f:id:bmf-dev:20171204132119p:plain

せっかくのアドベントカレンダーですが、あえて趣味に走りたいと思います。

準備

ビルド環境のセットアップが面倒なので、今回はFacebook公式のcreate-react-appというツールを使います。

npm install -g create-react-app

md-editorというアプリ名で環境を用意することにします。

create-react-app md-editor

次に、今回使うライブラリのインストールをしておきます。

cd ./md-editor

npm install --save marked

npm install

最後にサーバーを起動したら準備OKです。 npm start

実装

STEP1

実装に入る前に今回使用しない不要なファイルを削除しておきましょう。

  • App.css
  • App.test.js
  • logo.svg

src/index.js`src/App.jsで上記ファイルをインポートしている部分を削除しておきます。

それからsrc/App.jsのほうはreturn文の中身を空にしておきましょう。(ビルド時にreturn文が空で怒られますが一旦無視します。)

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App/>, document.getElementById('root'));
registerServiceWorker();

src/App.js

import React, {Component} from 'react';

class App extends Component {
  render() {
    return ();
  }
}

export default App;

STEP2

src以下にMarkdown.jsというファイルを作成します。 このファイルにはマークダウンのコンポーネントを実装していきます。

src/Markdown.js

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import marked from 'marked';

class Markdown extends Component {
  constructor(props) {
    super(props);
    this.state = {
      html: ''
    };

    this.updateMarkdown = this.updateMarkdown.bind(this);
  }

  updateMarkdown(event) {
    this.setState({
      html: marked(event.target.value)
    });
  }

  render() {
    const html = this.state.html;

    return (<div>
      <h1>Markdown Input</h1>
      <textarea onChange={this.updateMarkdown}></textarea>
      <h1>Markdown Output</h1>
      <div dangerouslySetInnerHTML={{
          __html: html
        }}></div>
    </div>);
  }
}

export default Markdown;

ほんの数行です。 これだけとりあえずマークダウンとして機能します。 ほぼ生のJSですね。 React特有なのはJSXくらいでしょうか。

STEP3

最後にMardown.jsApp.js内でインポートしましょう。

import React, {Component} from 'react';
import Markdown from './Markdown';

class App extends Component {
  render() {
    return (<Markdown/>);
  }
}

export default App;

動作確認

f:id:bmf-dev:20171204130049g:plain

ソースコードをハイライトしたい時にはisagalaev/highlight.js - githubを使ってmarkedをカスタマイズするといい感じになります。

参考

リポジトリ

ソースコードはbmf-san/til/javascript/md-editor/ - githubに置いてあります。

所感

Reactは素のJSに近い形でコーディングできるので、フレームワークに知識がロックインされづらいので好きです。

コードの説明はほとんど省きましたが、モダンなJSの話 by @bmf_sanの記事を見て頂れば大体わかるのではないかと思います。

当社ではVue.jsは使っていますが、Reactはまだ実案件で使っていません。

これを期にReactを使う機会が生まれればいいなぁ(願望)

明日9日目の担当は、今月入社されたばかりのHiroshi Satoさんです!