234
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

React.jsチートシート

概要

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からの削除)時

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
234
Help us understand the problem. What are the problem?