バージョン 1 の AngularJS で jQuery を内部的に利用できるのと同様に、こちらのページで基本的な使用方法を把握した React でも jQuery を内部的に利用した component を作成できます。本ページでは実際に jQuery プラグインをラップした簡単な React component のサンプルコードを示します。
関連ページ
簡単な例として、jQuery プラグインではなく jQuery 単体を利用する React component を考えます。jQuery 本体や jQuery プラグインのソースコードは JSX や ES6 を利用しておらず、Babel によるコンパイルは不要であることに注意します。ただし、import
や require
を利用している場合は 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.json
の dependencies
に追加されます。
"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 からハンドリングできています。
本ページでは特に 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 を React component でラップしてみます。ここでは先程と同様に npm で提供されているものを利用します。
npm install jquery@3.2.1 --save
npm install select2@4.0.5 --save
React のソースコードは以下のように記述します。
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();
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;
以下のような表示になります。
比較的古い記法が利用された jQuery プラグインの例として chosen を React component でラップしてみます。npm で提供されているものを利用します。
npm install jquery@3.2.1 --save
npm install chosen-js@1.8.2 --save
React のソースコードは以下のように記述します。
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();