LoginSignup
6
6

More than 5 years have passed since last update.

Reactでembed.jsを使ってリッチなコンテンツ表現

Posted at

embed.jsを利用すればリッチなコンテンツ表現ができます。embed.jsは特定のDOM要素を直接操作して、コンテンツをリッチ化するものと、リッチなコンテンツを文字列として返すものの二種類のAPIがあります。

Reactで使う場合、DOMを直接操作してしますと、VituralDOMの管理外のものが混在して、メモリ管理などが面倒になります。今回は、文字列として取得するAPIを利用してReactからembed.jsを利用します。

import

import 'embed.js';

ES6の記法で書いています。僕の環境ではimport EmbedJS from 'embed.js';のように記述できなかったので、全部をインポートしています。

embed.jsの利用

embed.jsで文字列として返還後の文字列を取得します。そのあと、dangerouslySetInnerHTMLを使ってコンテンツを表示します。コードはこんな感じ。

export default class Body extends React.Component {
  componentDidMount() {
    this.mounted = true;
    if (this.props.body && !this.state.body) {
      const options = {
        element: this.refs.body,
      };
      new window.EmbedJS(options)
        .text((htmlBody) => {
          if (!this.mounted) {
            return;
          }
          this.setBody(htmlBody);
        });
    }
  }

  componentWillUnmount() {
    this.mounted = false;
  }

  setBody(htmlBody) {
    this.setState({body: (<div dangerouslySetInnerHTML={{__html: htmlBody}} />)});
  }

  render() {
    return this.state.body ? this.state.body : (<div ref="body">this.props.body</div>);
  }
}

componentDidMountで、EmbedJSでコンテンツを変換します。コンストラクタに渡すオブジェクトでelement(DOM要素)を指定します。elementじゃなく、文字列で指定も一応は可能なんですが、

  • 文字列のエスケープを事前に自前でやっておかないとXSSの脆弱性になる
  • Twitterの埋め込みなどはelementで指定しないとエラーになる

など問題があるので、文字列じゃなくelementで指定するのがいいです。

そのあとに、textメッソドを実行して文字列に変換しています。textメソッドは非同期実行されて結果が返ってくるので、結果が帰る前にunmountされると警告がコンソールにでるので、unmountされそうになったらstateを更新しないようにしています。

mount状態を取得するisMountedは昔のReactは使えたのですが今はdeprecatedになっっているので、使わないで自前でmount状態を管理します。

でわでわ

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6