JavaScript
react.js

React.jsチートシート

More than 1 year has passed since last update.


概要

React = Facebook社が公開したUI構築のためのjsライブラリ


  • コンポーネントという単位で、UIごとに機能を宣言的に実装する



  • MVC/MVVMでいうところのView/View-modelのみを担当する


    • その他の部分はRedux/Fluxを組み合わせて構築する例が多い模様




  • HTMLのDOMを直接操作せず、Virtual DOM に対して操作を行う


    • Virtual DOMからHTML DOMへの反映はReactが効率的に行ってくれる



  • jQueryと併用できる


  • Bootstrapのような、UIのデザインライブラリとしての機能は持たない



導入

npmあるいはCDNで導入できる。


npm

$ npm install react

$ npm install react-dom


CDN

<script src="https://unpkg.com/react@15/dist/react.min.js"></script>

<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>


JSXの利用の有無

JSX = js内にXML風のマークアップを埋め込む記法。


  • JSXなしでもReactは利用できる(表記方法が通常のjsになる)

  • JSXを使う場合は、XML風の表記に加えてES6の構文が利用できる(harmony)

JSXを使う場合はいずれかの方法で運用する:


実行時に変換用のスクリプトを読み込み、変換する

JSXTransformer.js を使う。

この方法は読み込みのつど変換がかかるので、パフォーマンスは悪い(開発用)。

<script src="http://fb.me/JSXTransformer-0.12.1.js"></script>

<script type="text/jsx;harmony=true">
// JSX表記が可能となる
</script>

非推奨になった模様。

変わりにBabelを使う方法が紹介されていた。

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>

<script type="text/babel">
</script>


ビルド時にjsファイルをコンパイルする

react-toolsを使う。

# グローバルにreact-toolsをインストールする

# jsxコマンドが使えるようになる
$ npm install -g react-tools

# コンパイル
$ jsx --harmony path/to/src/ path/to/dest/

その他、ビルドツールやタスクランナーと組み合わせてコンパイルすることも可能な模様。


機能


コンポーネントとレンダリング


定義する



  • コンポーネントは、


    • ES5の場合、React.createClass() に対してオブジェクトを渡すことで生成する

    • ES6の場合、React.Componentクラスを継承したクラスを定義する



  • パラメータとなるオブジェクトには、最低限render() メソッドが必要となる


  • render() の戻り値は、コンポーネントオブジェクト(JSX)であること


// ES5表記

var Foo = React.createClass({
render(){
return (<div>Foo</div>);
},
});

// ES6表記
class Foo extends React.Component{
render(){
return (<div>Foo</div>);
}
});


入れ子にする

コンポーネント内に別のコンポーネントを含めることができる。

class Foo extends React.Component{

render(){
return (<div>Foo!</div>);
}
}

class Bar extends React.Component{
render(){
return (<div><Foo /> Bar!</div>);
}
}


レンダリング(DOMに出力)する

ReactDOM.render() でコンポーネントをDOMにレンダリングできる。

ReactDOM.render(

<Foo />, // 出力するコンポーネントを指定
$('#target')[0] // 出力先のelementを指定(jQueryを併用できる)
);


関数でコンポーネントを定義する

関数コンポーネント = 関数表記(function)により定義されたコンポーネント。

状態制御やクラス構造が不要な場合、関数コンポーネントを使うことで定義を省略できる。

// 関数コンポーネントを定義

// propsは引数として渡す
function Baz(props){
return (<div>Baz {props.msg}</div>);
}

// クラス定義したコンポーネントと同様に使える
ReactDOM.render(
<Baz msg={'message through props'}/>,
$('#sandbox')[0]
);


パラメータ(props)

propsは、コンポーネントの内外でパラメータをやりとりする仕組み。


propsを渡す

コンポーネントをレンダリングする際に、属性として変数を渡せる。


レンダリング時に渡す

ReactDOM.render(

// Fooコンポーネントにパラメータmsgとnumを渡す
<Foo msg="abc" num=123/>,
$('#sandbox')[0]
);


コンポーネントを入れ子に定義する際に渡す

class Bar extends React.Component{

render(){
// 同じくFooコンポーネントにパラメータを渡す
return(<div><Foo msg="xyz" num=999 /> Bar!</div>);
}
}


propsを参照する

渡されたpropsは、this.propsオブジェクトによって参照できる。


渡されたパラメータmsgとnumを参照する

class Foo extends React.Component{

render(){
return (<div>
<div>Foo!</div>
<div>message = {this.props.msg}</div>
<div>num = {this.props.num}</div>
</div>)
}
}


式展開する

propsにかぎらず、JSXオブジェクト内に中括弧 { } で式を囲むことで、その評価値をレンダリングできる。


props以外も展開できる

class Foo extends React.Component{

render(){
return (<div>
<div>Foo!</div>
<div>message = {'ふがふが'}</div>
<div>num = {SOME_CONSTANT}</div>
</div>)
}
}


コンポーネントを動的に構築する

JSXで定義したコンポーネントオブジェクトは、任意に変数に格納できる。

またそれを別のJSX内で展開できる。

function FooList(props){

// 変数に格納
const foo = (<Foo />);

// 配列に格納
let foos = [];
for(let i=0; i < props.length; i++)
foos.push(foo);

// 展開
return (<div>{foos}</div>);
}

ReactDOM.render(
<FooList length=3 />,
$('#sandbox')[0]
);


イベント


イベントを設定する

コンポーネントのイベントは、JSX内のイベント属性に、無名関数を渡すことで定義する。


クリック時にアラートを表示する無名関数を設定

class Foo extends React.Component{

render(){
return (<div onClick={function(){ alert('clicked'); }}>
Foo!
</div>)
}
}

また無名関数には、ES6のアロー関数を使うことができる。


アロー関数をイベントに設定

class Foo extends React.Component{

render(){
return (<div onClick={() => alert('clicked') }>
Foo!
</div>)
}
}

関数オブジェクトを渡せばいいので、メソッドや通常の関数でも可。


インスタンスメソッドをイベントに設定

class Foo extends React.Component{

onClick(){
alert('clicked');
}

render(){
// この書き方でも動くが、メソッド内のthisがundefinedになる
//return (<div onClick={this.onClick}>

return (<div onClick={() => this.onClick() }>
Foo!
</div>)
}
}



移譲する(delegateパターン)

上位のコンポーネントにイベントを移譲したい場合は、propsにイベントを設定する方法で対応できる。


propsを介したデリゲーション

class Foo extends React.Component{

render(){
return (
<button className="square" onClick={this.props.onClick }>
Foo
</button>
);
}
}

class Bar extends React.Component{
onClick(){
alert('clicked');
}

render(){
// クリックイベントをpropsとして渡す
return (<div>
Bar!
<Foo onClick={() => this.onClick() }/>
</div>);
}
}



状態制御

コンポーネントの状態は、インスタンス変数stateで保持する。

stateはコンストラクタ内で定義する。


コンストラクタとstateを定義する

class Foo extends React.Component{

constructor(){
super();

this.state = {
activated: false,
clicked: true,
};
}
// ...
}


stateを変更する際には、setState() を介して設定する。

こうするとコンポーネントの定義内(JSX)でstateを参照している場合に、再レンダリングがかかる。


クリック状態によって表示を更新する

class Foo extends React.Component{

constructor(){
super();
this.state = {
count: 0,
};
}

onClick(){
// クリックするたびに表示される数字を増やす
this.setState({
count: (this.state.count+1),
});
}

render(){
return (<div onClick={() => onClick() }>
{this.state.count}
</div>)
}
}



key

key = 連続する要素を識別するための名前のこと。

リスト構造の要素に対してkeyを指定することで、それらの要素が非効率に再レンダリングされることを防ぐ。


keyを指定する

class Bar extends React.Component{

constructor(){
super();
this.state = {
count: 0,
};
}

onClick(){
// クリックされるたびに、カウントを増やしてFooの数を増やす
this.setState({count: this.state.count+1});
}

render(){
// 繰り返しになるFooにkeyを指定して、レンダリング効率を向上させる
let foos = [];
for(let i=0; i < this.state.count; i++)
foos.push(<li><Foo key={i} /></li>);

return (<div onClick={()=> this.onClick() }>
Bar! <ul>{foos}</ul>
</div>);
}
}


keyはpropsと同じ記法で定義するが、this.props.keyとして参照することはできない


refs


  • ref = コンポーネント内の要素に対して任意につけられる名前のこと

  • refs = コンポーネント内で定義されたrefの一覧を保持するプロパティ


refsで要素を指定して操作する

class Foo extends React.Component{

constructor(){
super();
}

onClick(){
// ref=alphaの要素を取得・操作する
let alpha = this.refs.alpha; // React backing instance
let alphaDOM = ReactDOM.findDOMNode(alpha); // HTML Elem
let $alpha = $(alphaDOM); // jQuery obj
$alpha.html('ALPHA');
}

render(){
// 2つのdivにそれぞれ違うrefを付ける
return (<div onClick={()=> this.onClick() } >
Foo!
<div ref="alpha">alpha</div>
<div ref="bravo">bravo</div>
</div>);
}
}



ライフサイクルイベント

規定の名前のメソッドをコンポーネントに定義しておくと、コンポーネントの状態が変わった際にそれらが自動的に呼ばれる(= ライフサイクルイベント)。

constructor()render() もライフサイクルイベントのひとつ。


実装例

class Foo extends React.Component{

componentWillMount(){
// ...
}
}


一覧

引数/戻り値など詳細は公式のリファレンスを参照のこと

分類
メソッド
タイミング

Mounting(DOMへの追加時)
constructor()
コンポーネントのマウント(DOMへの追加)前

componentWillMount()
マウント前

render()
マウント時

componentDidMount()
マウント後

Updating(コンポーネントの更新時)
componentWillReceiveProps()
setProps()によるプロパティの更新時

shouldComponentUpdate()
stateかpropsの変更による更新の可否の問合せ

componentWillUpdate()
更新前

render()
更新時

componentDidUpdate()
更新後

Unmounting(DOMからの削除時)
componentWillUnmount()
アンマウント(DOMからの削除)時


参考