【React入門】Progateの学習をまとめてみた(備忘録)

# React とは
> Reactとは、ユーザーインターフェース構築のためのJavaScriptライブラリです。（React公式サイトより）

https://ja.reactjs.org/

ReactはJavaScriptのフレームワークとして、可読性が高く、非常に簡単にコードを書くことができます。そのため使用にあたり、JavaScriptの知識が前提条件となります。

## Reactルール
- App.js
JSXとJS ( JavaScript ) の記述部分に分かれている。
renderメソッドのreturn内のみ、JSXで記述する必要がある。
JSXで記述された要素はブラウザに表示される。
`renderメソッドの内`かつ`returnの外`にはJavaScriptを記述できる。


- 書き方
ほぼHTMLと同じ書き方ができる。HTMLではなくJSXと呼ぶ。
- 注意点
return内に複数の要素があるとエラーになるので、<div>タグで囲んで1つの要素として戻り値を設定すること。
- コメント
JSXを`{/* */}`で囲むと、その部分はコメントになる。
- imgタグの注意点
HTMLでは閉じタグが必要ないが、JSXでは閉じタグが必要になる。
`<img src='画像のURL' />`
のように、タグの終わりにスラッシュ「`/`」を記述すること。
- JSXにJSを埋め込む
JavaScriptの部分を中括弧{ }

上記を使用した実装例が下記となる。
```jsx:例
import React from 'react';

class App extends React.Component {
  render() {
    // 定数nameを定義してください JSコメント
    const name = "haru";
    
    // 定数imgUrlを定義してください JSコメント
    const imgUrl = "hogehoge.png";
    
    return (
      <div>
        {/* 定数nameを用いてにんじゃわんこと表示されるようにしてください JSXコメント*/}
        <h1>{ name }</h1>
        
        {/* 定数imgUrlを用いて画像が表示されるようにしてください JSXコメント*/}
        <img src={imgUrl} />
        
      </div>
    );
  }
}

export default App;
```

## イベント
イベントを用いると、「何かが起きたときに、処理を実行するように指定。
クリックされた時に処理を実行する」→ `onClick`イベントがある。
```jsx:例
<button onClick={() => { console.log("クリック"); }}>
    クリック
</button>
```

## state
次は「こんにちは、◯◯さん！」の◯◯という名前の部分が変わるようにする。
このように、ユーザーの動きに合わせて変わる値のことを、Reactでは`state`と呼ぶ。
流れとしては以下の考え方。
`state定義 → state表示 → state変更`

- state定義
stateは、constructorの中で、オブジェクトとして定義する。
```jsx:例
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    // stateを定義
    this.state = {name: 'haru'}
    
  }
  ...
```
- state表示
上記の例でいうと、this.stateはオブジェクトなので、`this.state.プロパティ名`とすることで、指定したstateのプロパティ名に対応する値を取得できます。
```jsx:例
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {name: 'haru'};
  }
  
  render() {
    return (
    	<div>
    	  <h1>こんにちは、{this.state.name}さん！</h1>

    ....以下略....
    
```
- state変更
`this.setState({プロパティ名: 変更する値})`とすることで、指定されたプロパティに対応するstateの値が変更される。
注意：「stateの値に直接代入することで値を変更してはいけない」という決まりがあります。値を変更したい場合は、`setState`を使うこと。

下記が、state定義、state表示、state変更を実装例である。
```jsx:例
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: 'haru' };
  }

  render() {
    return (
      <div>
        <h1>こんにちは、{this.state.name}さん！</h1>
        <button onClick={() => { this.setState({ name: "haru" }) }}>haru</button>
        <button onClick={() => { this.setState({ name: "jack" }) }}>jack</button>
      </div>
    );
  }
}

export default App;
```

---
### メソッド化
上記のstateをメソッド化する。
「stateのnameプロパティの値を変更する処理」を行う`handleClick`メソッドを作る。
```jsx:例
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {name: 'haru'};
  }
  
  // メソッド定義(引数:name)
  handleClick(name) {
    this.setState({name: name})
  }
  
  render() {
    return (
    	<div>
    	  <h1>こんにちは、{this.state.name}さん！</h1>
        {/* this.handleClick(引数)でメソッド呼び出し */}
        <button onClick={() => {this.handleClick('haru')}}>haru</button>
        <button onClick={() => {this.handleClick('jack')}}>jack</button>
        
      </div>
    );
  }
}

export default App;
```

---
### Reactのブラウザに表示される流れ
ブラウザに表示される流れは以下の
`App.js → index.js → index.html`へと順番に変換されていく。
具体的なコードは以下となる。
```jsx:App.js
import React from 'react';

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello World</h1>
        <p>一緒にReactを学びましょう！</p>
      </div>
    );
  }
}

export default App;
```
↓
```jsx:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
// 以下の定型文がreactで書いたコードをhtmlへ変換して、投げる文
ReactDOM.render(<App />, document.getElementById('root'));
```
↓
```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <title>React App</title>
  </head>
  <body>
    <!-- index.jsで指定したidをhtmlで指定する -->
    <div id="root"></div>
    
    <script src="bundle.js"></script>
  </body>
</html>
```

## CSS(スタイルシート)の表記
基本的にはhtmlと変わらないが、classを使用する際微妙な違いがある。
htmlではクラスを`class=" "`と定義していたが、jsxでは`className= ""`とする。
cssに表記する際は同じである。
```jsx:jsx
<h1 className="title">Hello World</h1>  {/* class=""ではない */}
```
```css:css
.title {
  color: #e6855e;
  background-color: #f3f372;
}
```

---
### コンポーネント
コンポーネントは「部品」や「パーツ」という意味。
Reactでは、見た目を機能ごとにコンポーネント化して、コンポーネントを組み合わせることでWebサイトの見た目を作る。
コンポーネントは主処理のApp.jsに渡すことで実装をする。
つまりブラウザ表示の流れは以下となる。
`コンポーネント(Language.js) → App.js → index.js → index.html`
```jsx:Language.js
import React from 'react';

class Language extends React.Component {
  render() {
    return (
      <div className='language-item'>
        <div className='language-name'>HTML & CSS</div>
        <img className='language-image' src='hogehoge.svg' />
      </div>
    );
  }
}

// Languageコンポーネントをエクスポート
export default Language;
```

```jsx:App.js
import React from 'react';
// Languageコンポーネントをインポート
import Language from './Language';

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>言語一覧</h1>
        <div className="language">
          {/* Languageコンポーネントを呼び出し */}
          <Language />
          
        </div>
      </div>
    );
  }
}

export default App;
```

##  props
作成したコンポーネントは何回でも使うことができる。しかし、そのまま使うと表示タイトルや表示画像はそのままで出力されてしまう。
App.jsから、各言語の名前と画像のデータをLanguageコンポーネントに渡すことによって、言語ごとに表示を変えることができる。App.jsから渡すこのデータをprops（プロップス）という。
`「props名=値」`という形で、コンポーネントを呼び出す箇所で渡せる。
```jsx:App.js
import React from 'react';
import Language from './Language';

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>言語一覧</h1>
        <div className='language'>
          {/* HTML & CSSのpropsを渡す */}
          <Language 
            name='HTML & CSS'
            image='hogehoge1.svg'
          
          />
          {/* JavaScriptのpropsを渡す */}
          <Language 
            name='JavaScript'
            image='hogehoge2.svg'
            
          />
          {/* Reactのpropsを渡す */}
          <Language 
            name='React'
            image='hogehoge3.svg'
            
          />
        </div>
      </div>
    );
  }
}

export default App;
```

```jsx:Language.js
import React from 'react';

class Language extends React.Component {
  render() {
    return (
      <div className='language-item'>
        {/* this.props.プロパティ名で汎用的に定義が可能 */}
        <div className='language-name'>{this.props.name}</div>
        <img 
          className='language-image' 
          src={this.props.image} 
        />
      </div>
    );
  }
}

export default Language;
```

##  まとめ
以上、基本的な処理をまとめてみた。
これ以降は応用部分になっていたので、別記事として残そうかなと思っている。