[自分用]Next.jsのカスタムフックとリフトアップ

## カスタムフック
カスタムフックを使う理由はコンポーネント分けと同じで、use系も使い回しができるようになる。
コンポーネント分けするよりもUIの自由度が高い！

### カスタムフックを使用するときに気をつけること
・hooksの命名は`use`から始めるべき（マニュアルにそう書いてある）。hooksと他の関数を見分けやすくするため。
・hooksはrerutnより前に記述する。
・hooksはJavaScriptの関数ではなく、Reactにおけるコンポーネント内で呼び出す。

### カスタムフックの利用方法
```useBgLightBlue.jsx
import { useEffect } from 'react';

export const useBgLightBlue = () => {
  useEffect(() => {
    console.log('こいつが実行されるよ');
    return () => {
      console.log('アンマウントも実行されるよ');
    }
  }, []);
}

```

```useInputArray.jsx
import { useCallback, useState } from 'react';

export const useInputArray = () => {
  const [text , setText] = useState("");
  const [array, setArray] = useState([1, 2, 3]);

  const handleChange = useCallback((e) => {
    setText(e.target.value);
  }, []);

  const handleAdd = useCallback(() => {
    setArray((array) => {
      if (array.some((item) => item === text)) {
        alert("既に存在しています");
        return array;
      }
      return [...array,text];
    });
  }, [text])

  return { text , array , handleChange , handleAdd};
}

```

```useCounter.jsx
import { useCallback, useState } from 'react';

export const useCounter = () => {
  const [foo, setFoo] = useState(1);
  const [isShow, setIsShow] = useState(true);

  const handleClick = useCallback(() => {
    setFoo(foo => foo + 1);
  },[]);

  const handleDisplay = useCallback(() => {
    setIsShow((isShow)=> !isShow);
  }, []);

  return { foo , isShow , handleClick , handleDisplay};
}
```
上記三つのコンポーネントが機能ごとにhooks分けされたもの。

```index.jsx
import { useCounter } from 'src/hooks/useCounter';
import { useInputArray } from 'src/hooks/useInputArray';
import { useBgLightBlue } from 'src/hooks/useBgLightBlue';

export default function Home() {
  const { foo, isShow, handleClick, handleDisplay } = useCounter();
  const { text, array, handleChange , handleAdd } = useInputArray();
  useBgLightBlue();

  return (
    <>
      {isShow ? <h1>{foo}</h1> : null}
      <button
        onClick={handleClick}>
        ボタン
      </button>
      <button
        onClick={handleDisplay}
      >
        {isShow ? "非表示" : "表示"}
      </button>
      <input type="text" value={text} onChange={handleChange} />
      <button onClick={handleAdd}>追加</button>
      <ul>
        {array.map((item) => {
          return <li key={item}>{item}</li>;
        })}
      </ul>
    </>
  )
}
```
この三つのコンポーネントをindex.jsxで読み込む。

### なぜコンポーネント分けではなく、カスタムフックを使用するのか
それは**カスタムフックの方がUIの自由度が高い**ため。

コンポーネントのようにUlで分けている分けではなく、あくまでも機能で分けているている。
そのため使い回したいがUlが一致していないときにカスタムフックが役に立つ。

だから「どこにこの機能を付与してもUIは統一！！」という場合はコンポーネント分けしてもいいのかなと思う。
（カスタムフックの方が「どんな機能を持っているのか」は把握しやすくなるけどね）

## リフトアップ
上記でuse系をさまざまなファイルで使用できるようになったけど、**状態の維持**はできない。
例えばカウンターで5にしたけど、ページ遷移をしたら1に戻ってしまう。理由は`const [foo, setFoo] = useState(1)`が再度読み込まれてしまい、初期値に戻るから。

そこで利用するのが_app.jsx!
_app_jsxでpropsとして渡したものは各ページでpropsとして受け取れる。
これを利用して、状態を複数ページで共有することができる。

```_app.jsx
import '@/styles/globals.css'
//インポート
import { useCounter } from 'src/hooks/useCounter';
import { useInputArray } from 'src/hooks/useInputArray';
import { useBgLightBlue } from 'src/hooks/useBgLightBlue';

export default function App({ Component, pageProps }) {
  //useCounterで設定した変数や初期値をcunterに代入。
  const counter = useCounter();
  const inputArray = useInputArray();
  useBgLightBlue();

  return (
    //counterの中身を展開してpropsとして渡す
    <Component {...pageProps} {...counter} {...inputArray} />
  )
}

```
```index.jsx
export default function Home(props) {
  //オブジェクトを分割代入しているので、順不同。
  const { count, isShow, handleClick, handleDisplay,text, array, handleChange , handleAdd } = props;
```