React から jQuery の資産を利用する
[最終更新] (2019/09/22 00:27:30)
最近の投稿
注目の記事

概要

バージョン 1 の AngularJS で jQuery を内部的に利用できるのと同様に、こちらのページで基本的な使用方法を把握した React でも jQuery を内部的に利用した component を作成できます。本ページでは実際に jQuery プラグインをラップした簡単な React component のサンプルコードを示します。

関連ページ

jQuery 単体を利用する例

簡単な例として、jQuery プラグインではなく jQuery 単体を利用する React component を考えます。jQuery 本体や jQuery プラグインのソースコードは JSX や ES6 を利用しておらず、Babel によるコンパイルは不要であることに注意します。ただし、importrequire を利用している場合は Browserify から jQuery 本体や jQuery プラグインのソースコードが参照できることが必要です。そのためには npm コマンドでインストールすると簡単です。

インストール可能なバージョン一覧を調べます。

npm view jquery versions --json

jQuery 3.2.1 をインストールする場合は以下のようにします。@ を指定しない場合は最新版がインストールされます。

npm install jquery@3.2.1 --save

アンインストール時は以下のようにします。

npm uninstall jquery@3.2.1 --save

うまく動作しない場合はキャッシュをクリアしてみると解消することがあります。

npm cache clear

package.jsondependencies に追加されます。

   "dependencies": {
+    "jquery": "^3.2.1",

React のソースコードは以下のように記述します。

index.js

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

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

registerServiceWorker();

MyComponent.js

import React from 'react';
import $ from 'jquery';

class MyComponent extends React.Component {

  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  componentDidMount() {
    this.$span = $(this.span);
    this.$span.on('click', this.handleClick);
  }

  componentWillUnmount() { // メモリリークを避けるために不要なリソースは解放します。
    this.$span.off('click', this.handleClick);
  }

  handleClick(e) {
    this.$span.text(this.$span.text() + ' クリックされました');
  }

  render() { // `ref` でコールバック関数 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
    // を登録しています。DOM ノード span を指す el を this.span に保存して、
    // render 後に実行されるライフサイクルフック `componentDidMount` 内で
    // jQuery オブジェクト化 `$()` します。
    return (
      <div>
        <span ref={el => this.span = el}>文字列</span>
      </div>
    );
  }
}

export default MyComponent;

クリックイベントを jQuery からハンドリングできています。

Uploaded Image

CDN

本ページでは特に create-react-app を利用していますが、他の環境でも同様です。こちらのページではその他にも CDN を利用した方法を記載していますが、その場合は以下のようになります。

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Hello World</title>
  <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">

class MyComponent extends React.Component {

  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  componentDidMount() {
    this.$span = $(this.span);
    this.$span.on('click', this.handleClick);
  }

  componentWillUnmount() {
    this.$span.off('click', this.handleClick);
  }

  handleClick(e) {
    this.$span.text(this.$span.text() + ' クリックされました');
  }

  render() {
    return (
      <div>
        <span ref={el => this.span = el}>文字列</span>
      </div>
    );
  }
}

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

</script>
</body>
</html>

jQuery プラグインを利用する例

select2

jQuery プラグインの例として select2 を React component でラップしてみます。ここでは先程と同様に npm で提供されているものを利用します。

npm install jquery@3.2.1 --save
npm install select2@4.0.5 --save

React のソースコードは以下のように記述します。

index.js

MyComponent の props として、値が変更された場合に発火するコールバック関数、初期状態で選択されている項目、選択項目一覧、をそれぞれ指定しています。

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

ReactDOM.render(
  <MyComponent onChange={value => console.log(value)} selectedValue="Y">
    <optgroup label="グループ A">
      <option value="X">XXX</option>
    </optgroup>
    <optgroup label="グループ B">
      <option value="Y">YYY</option>
    </optgroup>
  </MyComponent>,
  document.getElementById('root')
);

registerServiceWorker();

MyComponent.js

node_modules/ にローカルインストールされたファイル群から必要なファイルを import して利用します。MyComponent の外部から props.children を指定しているため、React 内で props.children が変更された際に componentDidUpdate ライフサイクルフックで jQuery にも変更されたことを知らせる必要があることに注意します。また、こちらのページで記載したとおり React における form 要素の value 属性は要素の値を拘束します。jQuery を利用する場合は form 要素の状態を React ではなく jQuery で制御したいため value ではなく defaultValue を利用します。チェックボックスやラジオボタンでは defaultChecked が利用できます。

import React from 'react';
import $ from 'jquery';
import 'select2/dist/css/select2.min.css';
import 'select2/dist/js/select2.min.js';

class MyComponent extends React.Component {

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  componentDidMount() {
    this.$select = $(this.select);
    this.$select.select2({
      width: '300px'
    });
    this.$select.on('change', this.handleChange);
  }

  componentDidUpdate(prevProps) { // React が DOM を変更した場合は jQuery にもその旨通知します。
    if (prevProps.children !== this.props.children) {
      // https://select2.org/programmatic-control/add-select-clear-items#selecting-options
      this.$select.trigger('change');
    }
  }

  componentWillUnmount() { // メモリリークを避けるために不要なリソースは解放します。
    this.$select.off('change', this.handleChange);
    // https://select2.org/programmatic-control/methods#destroying-the-select2-control
    this.$select.select2('destroy');
  }

  handleChange(e) { // 外部から渡されたコールバック関数を実行します。
    this.props.onChange(e.target.value);
  }

  render() { // `defaultValue` で初期値を指定できます。`value` と異なり初期値としてのみ機能します。
    return (
      <div>
        <select ref={el => this.select = el} defaultValue={this.props.selectedValue}>
          {this.props.children}
        </select>
      </div>
    );
  }
}

export default MyComponent;

以下のような表示になります。

Uploaded Image

chosen

比較的古い記法が利用された jQuery プラグインの例として chosen を React component でラップしてみます。npm で提供されているものを利用します。

npm install jquery@3.2.1 --save
npm install chosen-js@1.8.2 --save

React のソースコードは以下のように記述します。

index.js

MyComponent の props として、値が変更された場合に発火するコールバック関数、選択項目一覧、をそれぞれ指定しています。

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

ReactDOM.render(
  <MyComponent onChange={value => console.log(value)}>
    <option></option>
    <option>vanilla</option>
    <option>chocolate</option>
    <option>strawberry</option>
  </MyComponent>,
  document.getElementById('root')
);

registerServiceWorker();

MyComponent.js

この続きが気になる方は

React から jQuery の資産を利用する

残り文字数は全体の約 27 %
tybot
100 円
関連ページ
    概要 データをもとにして DOM を操作する D3.js (Data-Driven Documents) の基本的な使い方を記載します。特にバージョンは v5 を対象とします。 Gallery D3 API Reference Hello world HTTP サーバ 外部からデータを読み込むために CORS