Reactについてどんなものか知りたい人向け

## はじめに

Reactをほぼ使ったことのない初学者がReact公式ドキュメントをみて
理解した内容をアウトプットしております。

初学者だからこそ、初学者向けにかけているのではないかと思います。
至らない点がありましたらご指摘の方よろしくお願いします


## Reactとは？

Reactは、ウェブアプリケーションやユーザーインターフェース（UI）を作成するためのJavaScriptライブラリ。Facebook（現Meta）が開発したもので、ウェブページ上で動的な要素を効率よく作成・管理するために広く使われている。

　
再利用可能なコンポーネントで大規模アプリケーションの開発がしやく、
仮想DOMをつかった高速レンダリングが可能でユーザーの満足度も高い。

　
## 基本の記法
```diff_jsx
// 名前は大文字から始める
function Square(){
    // 1つのタグ内に収める（今回は<></>で収まっている）
    // 1つのタグ内でないとエラーが発生する
    return (
        <>
         {/* jsを使うときは{}で囲うことで使用可能} */}
            <button>{box.name}ボタン</button>
        </>
    );
}
```

上記のように記述することで部品（パーツ）として扱うことが可能になる。
このことをコンポーネントと呼ぶ。
コンポーネントについては次の章で紹介する。

　
#### またReactは、React独自の「条件分岐」や「繰り返し処理」を持っていないのでjavascriptを活用する。

条件分岐 例）if文の活用
```diff_jsx
let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);
```

繰り返し処理 例）mapの活用　
```diff_jsx
const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);
```

　
## コンポーネントの活用
前の章でコンポーネントは部品（パーツ）として使うことができると説明した。
これについて実際にコードで説明する

```diff_jsx
// Squareコンポーネントの定義
function Square(){
    return (
        <>
            <button>ボタン</button>
        </>
    );
}

// Squareコンポーネントを活用
export default function Box(){
    return (
        <>
            <Square />
            <Square />
            <Square />
        </>
    )
}
```

exportやdefaultなどの説明も後でするが、コンポーネントについて先に説明する。
上記のコードを確認してもらえたらわかるかと思うが
Boxのコンポーネント内でSquareコンポーネントを3回呼び出している。

今回はボタンだけのコンポーネントなので3つのボタンが表示される。
ただコンポーネントの名前を記述するだけでパーツとして呼び出すことが可能になって非常に便利だ。

ボタンのように小さな部品からページ全体などの大きな部品までコンポーネントで格納でき、繰り返し呼び出すことができるので開発が効率よくできる上に、部品など修正などをする際はコンポーネント内の修正で済むので保守もよい。

また部品として扱うにあたって、場所によって一部変更したい場合もある。
この場合はpropsを活用することで解決できる。

#### export defaultについて
他のファイルでこのコードを使いたい場合に記述する。
読み込みたいファイルでimport宣言することで扱うことが可能になる。
上記の例でいえば Boxがexportされているので
```diff_jsx
import Box from 'ファイル相対パス';
```
で上記のコード（コンポーネント）を扱うことが可能になる。

　
また、一つのファイルでexport defaultは１つまでなのでトップレベルのコンポーネントに記述する必要がある。

　
## propsについて
propsについて説明するためには親コンポーネントと子コンポーネントについても
理解していただく必要がある。

親コンポーネントは呼び出す側、使う側
子コンポーネントは呼び出される側、設定する側

propsは親コンポーネントから子コンポーネントに値を受け渡すものであり、
親からわたってきた値を元に表示などを変えることができる。
```diff_jsx
// 子コンポーネント　value(props)を受け取る
function Square({value}){
    return (
        <>
            <button>{value}ボタン</button>
        </>
    );
}

// 親コンポーネント
// Squareコンポーネントを活用
export default function Box(){
    return (
        <>
            {/* 子コンポーネントにprops(value)を渡す */}
            <Square value="1" />
            <Square value="2" />
            <Square value="3" />
        </>
    )
}
```
このようにpropsで子コンポーネントに値を渡すことで同じコンポーネントだが表示が変わる。
（1ボタン2ボタン3ボタン　と表示されるはず。）

※前の章でも述べたがjavascriptを使う際は{}で囲う必要があるので注意。

　
## インタラクティブなコンポーネント
インタラクティブは「対話」「双方向」という意味で
インタラクティブなコンポーネントというのはユーザーのアクションに応じで変化するコンポーネントのこと。

htmlだけのコードからjsを組み込んで動きを出すという感じでとらえてもらえたらと思う。

```diff_jsx
function Square({value}){
    {/* 子コンポーネントに関数を追加 */}
    function handleClick(){
        console.log('clicked');
    }
    return (
        <>
            {/* onClickを配置してhandleClickを発火させる仕組みを作る */}
            <button onclick={handleClick}>{value}ボタン</button>
        </>
    );
}

// 親コンポーネント
export default function Box(){
    return (
        <>
            {/* 子コンポーネントにprops(value)を渡す */}
            <Square value="1" />
            <Square value="2" />
            <Square value="3" />
        </>
    )
}
```
こうすることで　1ボタン2ボタン3ボタン　のどれを押しても
consoleでclickedを表示されることが確認できる。

今回は関数の処理がconsoleだが、ここを変えて表示を変えることもできる。
表示を変えるためにはフックを学ぶ必要がある。

　
## Reactフックについて

フックという言葉は、プログラムの中に独自の処理を割りこませるために用意されている仕組みのことを指す。

フックはReactの独自の機能ではなく、過去の案件でWordPressの中でもフックがあり
なじみのある人もいるかと思います。

では早速Reactフックの基本useStateについて解説します。

```diff_jsx
// reactからuseStateをインポート
import { useState } from 'react';

function Square(){
    {/* フックの追加 */}
    const [value, setValue] = useSteate{null};

    {/* handleClickの処理の変更 */}
    function handleClick(){
        setValue('X');
    }
    return (
        <>
            <button onclick={handleClick}>{value}ボタン</button>
        </>
    );
}

// 親コンポーネント
export default function Box(){
    return (
        <>
            <Square />
            <Square />
            <Square />
        </>
    )
}
```

まず、動きについて解説すると
ブラウザには　ボタンボタンボタン　と表示されている。

このどれかをクリックするとクリックしたボタンの前に　X　という文字が出現する。
ほかのボタンも同様の動作をする。
このようにコンポーネントは独立しており、1つ押してすべてが変化するのではないことに注意しよう。※１つを押下してすべてのコンポーネントを変更する方法もあるが今回は触れない。


useStateの記法は
```diff_jsx
const [value, setValue] = useSteate{null};
```
```
const [変更したい変数, set変更したい変数] ＝　useState{初期値}
```
このようにまず準備する。
こうすることでvalueの中にuseStateの｛｝内の初期値を代入し、
保持することができる。

 　
次に変更させる処理を書く
```diff_jsx
function handleClisk(){
    setValue('X');
}
```
この関数が発火した時、setValueの値に X を代入する。
そうするとvalueの方にも代入され{value}の値がnullから X に変更される。

発火させるためのコードと表示させるためのコードを記述を追加し完成させる
```diff_jsx
function Square() {
    const [value, setValue] = useState(null);
    function handleClick(){
        setValue('X');
    }

    return (
        <>
            <button onClick={handleClick}>
                {value}ボタン
            </button>
        </>
    )
```
ボタン　をクリックすることで　Xボタン　と表示が切り替わる。

　
## stateのリフトアップとは？
Stateのリフトアップは、コンポーネントの情報を親コンポーネントで管理すること。
先のほどの例では、子コンポーネントであるSquareにStateの記述があるがこれを親にきじゅつしてpropsで渡すようにする。

```diff_jsx
import { useState } from 'react';

// 子コンポーネントにStateを持たせない。
// propsでvalueとonSquareCliskを受け取り表示する
function Square({ value, onSquareClick }) {
  return (
    // クリックでonSquareClickを発火させる
    <button className="square" onClick={onSquareClick}>
        {value}
    </button>
  );
}

// 親コンポーネントにStateを持たせる
export default function Board() {
  const [squares, setSquares] = useState(Array(3).fill(null));

// クリックした子コンポーネントの引数をみてStateの値を変える */}
  function handleClick(i) {
    const nextSquares = squares.slice();
    nextSquares[i] = 'X';
    // Stateで変更された値がpropsで子コンポーネントに渡され表示が切り替わる。*/}
    setSquares(nextSquares);
  }

  return (
    <>
      <div className="board-row">
        {/* クリックすることで子コンポーネントのクリックイベントが発火➜handleClickが発火*/}
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
    </>
  );
}

```

コメントアウトで細かく書いたつもりだが、抜け漏れ等でわかりづらかったらぜひコメント下さい。

再度Stateのリフトアップの説明をすると、
子コンポーネントにStateを持たせるのではなく
親コンポーネントにStateを持たせて保守、管理をしやすくする仕組み。

上記のコードのポイントとして
```diff_jsx
<Square value={squares[0]} onSquareClick={() => handleClick(0)} />
```
ここの親コンポーネントのロジック
アロー関数を使っているがこれはなぜなのか？
```diff_jsx
<Square value={squares[0]} onSquareClick={handleClick(0)} />
```
これではいけないのか？

結論、アロー関数がないとエラーになってしまう。
その理由として　handleClick関数の呼び出しがレンダー時に実行されてしまうからです。
そうするとhandleClick関数はStateを更新するのでさらにレンダーされ、レンダーによってまたhandleClickが呼び出せれて、Stateを更新し、、、、
無限ループに入り危険です。

なのでこれをアロー関数にしてpropsで子コンポーネントに渡して
onClick={onSquareClick}
をセットすることでエラーが解消される。

上記のコードはつまり
onClick={handleClick(0)}と同じ意味になる。