React基本事項の備忘録①

# はじめに
JavascriptのライブラリであるReactに興味がありProgateの第一章を終えたので、備忘録としてまとめたいと思います。

# Reactとは
Facebook社が開発したJavaScriptのライブラリです。
よく`vue.js`と比較されることが多いですが、vue.jsの方はフレームワークになります。

ReactはWebのUIをつくるために用いる技術で`SPA（シングルページアプリケーション）`を作りたい時にReactは親和性が高いです。ただ、SPA = Reactという関係性ではないので注意です。

## HTMLはrenderメソッド内に記述する

```php:App.js
import React from 'react';

class App extends React.Component {
  render (){
    return (
      <h1>hello World!</h1>
  );
 }
}
```
`remder`メソッドの`return`内にHTMLを記述することでブラウザに文字列を表示することができる。

## JSX記法
**JSX**とはJSファイルにHTMLを簡単に記述するためのJavaScriptの拡張言語です。
JSXはそのままだとブラウザが読み込むことができないので、**トランスパイラ**とよばれるもので翻訳していきます。
トランスパイラには**Babel**や**TypeScript**などがあります。

上の例のようにReactでは基本的にJSファイルにHTMLを記述していきます。
HTMlと同じように`h1タグ`や`pタグ`、その他の`divタグ`を使用できます。

```php:App.js
import React from 'react';

class App extends React.Component {
  render (){
    return (
     <div>
       <h1>hello World!</h1>
       <h2>hello World!</h2>
       <p>hello World!</p>
     </div>
  );
 }
}
```
上の例では、`return`内が複数行になっています。
この場合は`divタグ`を１つ親要素として記述し、その中にまとめて要素を記述していきます。
こうしないとJSX記法ではエラーが発生してしまいます。

## JSX記法での空要素
HTMLでは`imgタグ`や`inputタグ`に閉じタグが不要でしたが、下のコードのようにJSX記法では閉じタグの前に`/`が必要です。

```php:App.js
import React from 'react';

class App extends React.Component {
  render (){
    return (
      <img src="test.png" /> #閉じタグの前に/を入れる
  );
 }
}
```

## Reactファイルの構成

```php:App.js
{/* お作法やおまじないみたいなもの　*/}
import React from 'react'; 

{/* React.Componentを継承するクラスの定義　*/}
class App extends React.Component {　
　{/* returnを戻り値とするrenderメソッドを定義　*/}
  render () {　　
    return (
      <h1>hello World!</h1>
  );
 }
}

{/* クラスをエクスポート（他のファイルでも使用できるようにする）　*/}
export default App; 
```

## JSXとJSの範囲
JSXとJSをどこに書いたらいいか迷いますが、JSXはrenderメソッドの`return`内に記述し、JSはクラス内に記述していきます。例えばrenderメソッドのreturn外で変数を定義し、その値をreturn内に渡すことができます。

また、JSX記法で変数を宣言する際は**キャメルケース**で命名するのが慣例です。
キャメルケースとは単語の区切りを大文字にする記述方法です。
`例　const userName = "アナゴ"`

```php:App.js
import React from 'react';

class App extends React.Component {
  render() {
    // 定数nameを定義
    const name = "アナゴ";
    
    // 定数imgUrlを定義してください
    const imgURL = "test.png";
    
    return (
      <div>
        {/* 定数nameを用いてアナゴと表示する*/}
        <h1>{ name }</h1>
        
        {/* 定数imgUrlを用いて画像を表示する */}
        <img src={imgURL} />
        
      </div>
    );
  }
}

export default App;
```
` <h1>{ name }</h1>`のようにreturn外で定義した変数をreturn内で反映させるためには`{ }`を用います。
imgタグの場合は`<img src={imgURL} />`というように記述します。

##  イベントとstateについて
Reactではユーザーの操作に合わせて動的にviewを変化させることができます。
その際に必要な要素が**イベント**と**state**です。例えばユーザーがあるボタンをクリックしたら文字列が変化するといった場合です。

### イベントの書き方
return内のタグ内にイベント名と処理内容を記述します。
`() => {　処理内容　}`の部分はES2015のアロー関数で記述しています。

```php
<button イベント名 = {() => {　処理内容　}}>ここをクリック!</button>
```
一例としてボタンがクリックされたらコンソールに名前が表示されるという挙動を`onClickイベント`で記述していきたいと思います。

```php:App.js
import React from 'react';

class App extends React.Component {
  render() {
    return (
    	<div>
    	  <h1>こんにちは、アナゴさん！</h1>
          {/* buttonタグ内に、コンソールに名前を出力するonClickイベントを追加 */}
          <button onClick={() => {console.log('アナゴ')}}>アナゴ</button>
        
          {/* buttonタグ内に、コンソールに名前を出力するonClickイベントを追加 */}
          <button onClick={() => {console.log('カツオ')}}>カツオ</button>
        </div>
    );
  }
}

export default App;
```

### stateとは
先程、Reactではユーザーの操作に合わせて動的にviewを変更できると説明しましたが、ユーザーの動きに合わせて値が変わることをReactでは**state**と呼びます。
stateを使用して表示を変更させるためには三段階の工程が必要です。

**1. stateを定義する**
**2. stateを表示する**
**3. stateを変更する**

#### 1. stateを定義する
stateは`オブジェクト`として定義します。
オブジェクトとは複数の値をプロパティという名前をつけて管理できるものです。

```php
# アナゴと男性という複数の値に対してnameとsexというプロパティをつけて管理
const user = {name: "アナゴ", sex: "男性"}
``` 
具体的な定義の仕方は以下の通りです。

```App.js
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {name: 'アナゴ'};
  }
}
```
クラスの中に`constructor(props)`を記述しその中に`super(props)`を記述します。
この部分は定型文みたいなものです。
stateの定義は`this.state = {name: 'アナゴ'};`の部分です。
`{name: 'アナゴ'}`というオブジェクトを`this.state`に代入しています。

ここで定義したstateの値は**初期値**になります。

#### 2. stateを表示する
this.stateはオブジェクトなので`this.state.プロパティ名`で値を取得することができます。

```App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    {/* stateの初期値を定義 */}
    this.state = {name: 'アナゴ'};
  }
  
  render() {
    return (
    	<div>
　　　　　　{/* stateの表示 */}
    	  <h1>こんにちは、{this.state.name}さん！</h1>
        </div>
    );
  }
}

export default App;
```

#### 3. stateを変更する
`this.setState({プロパティ名: 変更する値})`とすることで指定されたプロパティに対応するstateの値が変更されます。これで例えば、ボタンがクリックされたら表示されるnameを変更するという挙動を実現させることができます。

```php:App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
　　 {/* stateの初期値を定義 */}
    this.state = {name: 'アナゴ'};
  }
  
  render() {
    return (
    	<div>
    	  <h1>こんにちは、{this.state.name}さん！</h1>
    	  {/* onClickの処理に、stateを変更する処理を追加 */}
        　<button onClick={() => {this.setState({name: "アナゴ"})}}>アナゴ</button>
        
        　{/* onClickの処理に、stateを変更する処理を追加 */}
        　<button onClick={() => {this.setState({name: "カツオ"})}}>カツオ</button>
      </div>
    );
  }
}

export default App;
```

### メソッドの定義
メソッドはクラスの中で定義します。`メソッド名(){　処理内容 }`で定義できます。

```php:
class App extends React.Component {
  constructor(props) {
    super(props);
　　....
  }
  メソッド名() {
    処理内容
  }
}
```
先程のボタンをクリックしたら表示が変わる挙動をメソッド化していきましょう。
onClickイベントでメソッドを呼び出します。
`onClick = {() => {this.メソッド名()}}`と記述することでメソッドを呼び出します。
今回はメソッド名を**handleClick**とします。

```php:
class App extends React.Component {
  constructor(props) {
    super(props);
　　....
  }
  handleClick() {
    処理内容
  }
  render() {
    return(
      <button onClick = {() => {this.handleClick()}}>アナゴ</button>
    );
  }
}
```

#### メソッドに引数を渡す
handleClickメソッドに引数を渡すことでstateを変更します。
今回はnameを引数として渡します。

```php:App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    {/* stateの初期値を定義 */}
    this.state = {name: 'にんじゃわんこ'};
  }
  
  // handleClickメソッドを定義
  handleClick(name) {
    this.setState({name: name});
  }
  
  render() {
    return (
    	<div>
    	  <h1>こんにちは、{this.state.name}さん！</h1>
    	  {/* onClickイベント内の処理を、handleClickメソッドを呼び出す処理に書き換えてください*/}
          <button onClick={() => {this.handleClick('アナゴ')}}>アナゴ</button>
        
    	  {/* onClickイベント内の処理を、handleClickメソッドを呼び出す処理に書き換えてください*/}
          <button onClick={() => {this.handleClick('カツオ')}}>カツオ</button>
      </div>
    );
  }
}

export default App;
```

### おまけ
onClickイベントとstate,メソッドを応用してボタンがクリックされるたびにカウントが1足されるというものが作れます。

```php:App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
  }
  
  // handleClickメソッドを定義
  handleClick() {
    this.setState({count: this.state.count + 1});
  }
  
  render() {
    return (
      <div>
        <h1>
          {this.state.count}
        </h1>
        {/* <button>タグ内でonClickイベントを追加 */}
        <button onClick={() => {this.handleClick()}}>+</button>
        
      </div>
    );
  }
}

export default App;
```

以上です！