ReactのクラスコンポーネントとかJSXとかコンテキストとか調べてみた

# はじめに
reactに関するメモ

# 参考
[React.js&Next.js超入門](https://www.amazon.co.jp/React-js-Next-js%E8%B6%85%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798056928/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=react&qid=1577723599&sr=8-1)

# まとめ
* アクセスするとindex.htmlが読み込まれる。
* index.htmlを読み込む際に、index.jsが読み込まれ実行される
* index.jsの中でAppコンポーネントが読み込まれ表示される
* Appコンポーネントから様々なコンポーネントが利用され、そのコンポーネントが更にコンポーネントを利用している形
* コンポーネントごとにファイルを分割してそれぞれを組み合わせて開発するスタイル


# Ractとは
* 仮想DOMを構築して、仮想DOMを操作することで本来のDOMに反映
* なにかの値を変化すると、それがすぐに反映される仕組みのこと
* npm/Node.jsを用意。プロジェクト(必要なものが一式揃っている)を用意して、これをベースにして開発する

# プロジェクトの作成
```bash

$ npx create-react-app react_app
or
$ npm init react-app react_app
```

react_appがReactアプリケーションのプロジェクト。アプリケーション開発に必要なものが揃えられている。

### プロジェクトのファイル
* public/inddex.html アクセス時に表示。
  - Reactの表示を組み込む場所を提供する
* src/index.js 
  - サーバー側でindex.htmlを読み込んだら、index.jsを読み込むようになっている
* src/App.js
  - **ここがコンポーネントのルートで、ここから様々なコンポーネントを呼び出して、利用。その呼出したコンポーネントがまたコンポーネントを利用している形になる**

アクセスするとindex.htmlが読み込まれる。
index.htmlを読み込む際に、index.jsが読み込まれ実行される
index.jsの中でAppコンポーネントが読み込まれ表示される

### index.js

```react

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

//ここでid=rootのタグにAPPコンポーネントを表示しているだけ
ReactDOM.render(<App />, document.getElementById('root'));
```

### APP.js
表示されているコンポーネントの中身。デフォルトはここが表示されているだけ。

```react

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
```


# プロジェクトの実行
```
npm start
```
実行するとwebブラウザでhttp://localhost:3000が実行される。npm startは開発用のWebサーバーを起動してそこでwebアプリケーションを公開し、アクセスできる状態にする。

# プロジェクトのビルド
ビルドをしてwebアプリケーションに公開に必要なファイルを生成する。

```
npm run build
```
build/ がプロジェクトをビルドしたアプリケーションでこれをwebサーバにアップロードすればよい。

# 基本
* index.htmlの中にあるid=rootタグの中の表示を切り替える。
* 切り替える表示の内容はindex.jsなどに書く
  -　挿入したいHTMLを返す関数やアロー関数
  -　ReactDOM.renderでレンダリングする

# JSX
* JavaScriptの文法拡張。**BabelがJSXのタグをJavaScriptのコードに変換している**

```
<script type="text/babel">これでBabelによってコンパイルされるようになる
```

* 切り替える表示の内容はindex.jsなどに書く場合、createElementで書くと複雑な場合面倒。そこでJavaScriptの中で直接HTMLをかける仕組みを持つ、それがJSX
* JSXを返す関数を用意から、アロー関数を使う
  - アロー関数とはその場限りで使う関数。**呼び出しと定義を一緒にできるイメージ**
  - 記述した関数定義をその場で実行できる。その中にJSXを利用する

```react

let el=(
    <div>
        <h2></h2>
    </div>
);
```

# コンポーネント
## 利用の仕方
タグで呼び出す
<コンポーネント名/>

ここに関数でreturnしたHTMLがはめ込まれる
## 関数

```react

const msg1={ fontSize: "20px"  }
function コンポーネント名(props){
    return JSXによる表示 props.styleで取り出せる
}
<コンポーネント名 style="{msg1}">
```

## クラス
```react

class コンポーネント名 extends React.Component{

//メンバ
x=0;
y=0

constructro(props){
  //ここでメンバにセットして、renderでセットされたメンバを利用してHTML表示
}
//必ず用意
rehder(){
    return JSXによる表示
}
}
```

# ステート
### 値を保管する場所
* プロパティ
  - コンポーネントクラスのメンバ
* props
  - read only。コンポーネントの属性をまとめて保管するためのもの
* ステート(state)
  - 各コンポーネント単位。コンポーネントの現在の状態を扱う。
  - **ステートの値を操作することで、コンポーネントの状態を操作できる**
  - **ただ値を変更するだけで、自動的に表示が変えられる。ReactDOM.render必要ない**
  - this.state ={ 値を用意する }　してその値をHTMLの箇所で利用すると、更新される

```react
import React, { Component } from 'react';
import Rect from './Rect';
import './App.css';


class App extends Component {


  msgStyle = {
    fontSize:"24pt",
    color:"#900",
    margin:"20px 0px",
    padding: "5px",
    borderBottom:"2px solid #900"
  }
  btnStyle = {
    fontSize:"20pt",
    padding:"0px 10px"
  }


  constructor(props){
    super(props);
    this.state = {
      msg:'Hello',
    };
    //タイマーで更新されるたびに、表示が変わる
    let timer = setInterval(()=>{
      this.setState((state)=>({
        msg: state.msg + "!"
      }));
    }, 10000);
  }


  render(){
    return <div>
      <h1>React</h1>
      //ここでステートを利用
      <p style={this.msgStyle}>{this.state.msg}</p>
      <p style={this.msgStyle}>{this.props.msg}</p>
    </div>;
  }


}


export default App;

```

# イベントのバインド
onClickへの関数設定

```html

<button onClick="this.xxx">
```

メソッドのバインド

```react

this.xxx = this.xxx.bind(this)
```

```react

class App extends Component {


  msgStyle = {
    fontSize:"24pt",
    color:"#900",
    margin:"20px 0px",
    padding: "5px",
    borderBottom:"2px solid #900"
  }
  btnStyle = {
    fontSize:"20pt",
    padding:"0px 10px"
  }


  constructor(props){
    super(props);
    this.state = {
      counter:0,
      msg:'count start!',
    };
    //紐付け
    this.doAction = this.doAction.bind(this);
  }

  //紐付けられるメソッド
  doAction(e){
    this.setState((state)=> ({
      counter: state.counter + 1,
      msg: 'count: ' + state.counter
    }));
  }

  render(){
    return <div>
      <h1>React</h1>
      <p style={this.msgStyle}>{this.state.msg}</p>
      //利用
      <button style={this.btnStyle} onClick={this.doAction}>Click</button>
    </div>;
  }
```

# コンテキスト
コンポーネントに共通の値をもたせる

```react

import React, { Component } from 'react';
import Rect from './Rect';
import './App.css';


let data = {title:'Title',
  message:'this is sample message.'};

//クラスの外で宣言
const SampleContext = React.createContext(data);


class App extends Component {


  render() {
    return (
      <div>
        <h1>Context</h1>
        <Title />
        <Message />
      </div>
    );
  }
}


class Title extends Component {
  static contextType = SampleContext;


  render(){
    return (
      <div>
        <h2>{this.context.title}</h2>
      </div>
    );
  }
}


class Message extends Component {
  static contextType = SampleContext;


  render(){
    return (
      <div>
        <p>{this.context.message}</p>
      </div>
    );
  }
}


export default App;
```