webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

Reactが理解できない人のための、Reactチュートリアル①

f:id:s-uotani-zetakansu:20180118120800j:plain

こんにちは、さもです。

Reactが流行りだしてからしばらく経ちますが、フロントエンド、WEBサーバーサイドエンジニアの方々はもうReactを触ってみましたか?

Reactは一回理解できると、とても楽しく、(Reactに限らず仮想DOMは)強力に感じるのですが、初めはコンポーネントやステートなどの概念が理解できず、なかなか使ってみることが出来ませんでした。

僕は本家チュートリアルを頑張って読みながら実装してなんとか理解できました。

ですが、本家チュートリアルは英語で書かれてあり、かつ、結構なボリュームがあります。英語が苦手な人が始めてみるには少しハードルが高いのではないでしょうか。

そこで、シンプルな例を踏まえて、僕なりのチュートリアルをこれから書いていこうと思います。チュートリアルでは、簡単なフォームを実装してみたいと思います。

僕もReactを始めたばかりなので厳密には間違っているところもありますが、ざっくりとReactとはこんなものというのを感じ取ってもらえればと思います。

第1回目は「なぜReactを使うのか」について書いていきます

index

  1. なぜReactを使うのか
  2. componentとstate(これから書く)
  3. props(これから書く)

スポンサーリンク

なぜReactを使うのか

Reactとは何か

Reactは、動きのあるUI(ユーザーインターフェース)を実装するためのJavaScriptライブラリです。

仮想DOMと言われる設計書を記述しておくと、それを元に実際のDOM要素を生成し、画面に表示します。

もし画面に変更があった場合は、変更すべきところだけを再描画するので、高速です。

これまで通り、jQueryを使うこととの違い

動きのあるUIを実装するだけであればjQueryでも問題ありません。実際、jQueryは今でもいろんなところで開発に使われ動いています。

ご存知のようにjQueryでは、クラスやidを指定し、対応するDOM要素に対して変更を加えていきます。

一方で、Reactは、コンポーネント(DOMの設計書)と、コンポーネントが持つステートを元に実際のDOM要素を描画します。ステートと画面の状態は1対1に結びつき、ステートを変更することでDOMに変更を加えていきます。

よくわからんので、ちょっと例を見てみましょう。

(リセットボタンの例)

  • jQuery
<form>
  <label>Name:</label>
  <input type='text' id='userName' />
  <button type='button' id='reset'>リセット</button>
</form>

<script>
  $('#reset').on('click', function(){
    $('#userName').val('');
  })
</script>

*React

class TestForm extends React.Component {
  constructor(props){
    super(props);
    this.state={ name: '' }
  }
  
  reset(){
    this.setState({ name: '' })
  }
  
  render(){
    return(
      <form>
        <label>Name:</label>
        <input
          type='text'
          onChange={(e) => this.setState({name: e.target.value})}
          value={this.state.name}
        />
        <button type='button' onClick={this.reset}>リセット</button>
      </form>
    )
  }
}

Reactの方が記述量が多くて読むのが大変かもしれません。

jQueryでは、リセットボタンが押されると、$('#reset').on('click', function(){が発火し、関数内の処理を実行しています。シンプルなので、本当にこれだけであればReactを使わなくていいと思います。

Reactでは、フォーム一つを作るのでもそこそこ記述しなくてはなりません。

<input type='text' onChange={(e) => this.setState({name: e.target.value})} value={this.state.name} />を例にとって説明します。

まず、Reactのフォーム内の値(inputのvalue)も画面の「状態」と考えます。名前に「Yamada」と「Tanaka」を入れた場合ではそれぞれ別の状態になります。

なので、inputに入力があった場合は、画面の状態が変わった(正しくは変える?)ので、画面の状態とステートを1対1にしておくためにステートを更新しなくてはなりません。それがonChange={(e) => this.setState({name: e.target.value})}の部分です。this.setStateでステートを更新しています。

逆に、inputのvalueはステートで管理されているものを用いなくてはいけません。それが、value={this.state.name}の部分です。this.state.nameでnameという名前がついたステートと結び付けられます。

ユーザーが名前を入力したときは、

「Tanaka」と入力(onChangeが発火)
↓
setStateでステートを更新
↓
ステートが更新されたので、inputのvalue(this.state.name)が自動的に更新される

という流れになります。

では、リセットボタンの実装ですが、まずステートをすべて空文字に更新するresetという関数を作ます。

reset関数を呼び出しているのは、リセットボタンのonClickです。

onClickが発火するとreset関数が呼び出され、ステートを空に更新。すると、更新されたステートと結びついたinputが自動的に更新されます。

リセットボタンクリック(onClickが発火)
↓
reset関数内でステートを空文字更新
↓
ステートが更新されたので、inputのvalue(this.state.name)が自動的に更新される

ユーザーが入力したときと流れは同じですね。

Reactでは、ステートさえ更新すれば、自動的に画面が更新されるので、プログラム側ではステートをどう更新するかに集中することが出来ます。

なぜReactを使うのか

フォーム一つでも結構大変ですよね。

これにあれやこれやと機能をつけていくことを考えると。。。

と、考えたときに、実はReactの方が楽なんです。

jQueryでは、入力値に対して内部で持つフラグや変数をあれやこれやとこねくり回し、やがて巨大で複雑なプログラムが完成します。

しかも1画面で使うプログラムが1ファイルに散らばっているというのが現実だと思います。

一方、Reactでは、ある部品(inputなど)の状態はあるステートによって完全にきまります。関数(機能)が増えても、各関数はステートだけを見て、更新していればいいのです。

また、関数は自分が作用する部品に隠蔽されているので、散らばっていく心配もありません。

最後に、上のプログラムに以下の機能を追加してみましょう。

  1. 名前をボタンの横に表示する
  2. 表示した名前を隠したり表示したりするボタン

jQueryでの実装

<form>
  <label>Name:</label>
  <input type='text' id='userName' />
  <button type='button' id='reset'>リセット</button>
  <div id="displayName"></div>
  <button type='button' id='displayFlg'>表示</button>
</form>

<script>
  $('#reset').on('click', function(){
    $('#userName').val('');
  });

  $('#userName').on('change', function(){
    $('#displayName').text($(this).val());
  });

  $('#displayFlg').on('click', function(){
    $('#displayName').hide();
    if($(this).text() == '表示'){
      $(this).text('非表示');
    }else{
      $(this).text('表示');
    }
  });
</script>

Reactでの実装

class TestForm extends React.Component {
  constructor(props){
    super(props);
    this.state={
      name: '',
      displayName: true
    }
  }
  
  reset(){
    this.setState({ name: '' })
  }
  
  toggleDisplayFlg(){
    this.setState({ displayName: !this.state.displayName })
  }
  
  render(){
    return(
      <form>
        <label>Name:</label>
        <input
          type='text'
          onChange={(e) => this.setState({name: e.target.value})}
          value={this.state.name}
         />
        <button type='button' onClick={this.reset}>リセット</button>
        <div style={{display: this.state.displayName ? 'block' : 'none'}}>
          {this.state.name}
        </div>
        <button type='button' onClick={this.toggleDisplayFlg}>
          {this.state.displayName ? '表示' : '非表示'}
        </button>
      </form>
    )
  }
}

どうでしょう?

Reactは仮想DOMもプログラムに含まれるため見た目は複雑になりがちですが、jQueryよりも直感的に実装できたのではないでしょうか。

次回は実際にReactのインストールから始め、簡単に構文を説明したあと、フォームを実装していきたいと思います。

がんばって書いていきます。

読者登録はこちらからお願いします。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT-ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT-ONE)

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで