React context, memo, Ref メモ書き

# 1.はじめに
曖昧な理解のため、自分が見返すためのメモ書きのような感覚でまとめていきます。
少しでも参考になれば幸いです。
# 2.useContext
### useContextとは
> useContext はコンポーネントでコンテクスト (Context) の読み取りとサブスクライブ（subscribe, 変更の受け取り）を行うための React フックです。

https://ja.react.dev/reference/react/useContext

### 特徴
- コンポーネント間でデータを共有するためのフック
- ネストの深いコンポーネントにもデータを渡せる（Prop Drilling 解消）
- Provider を使って値を渡し、useContext で取得。

### 使用方法
- `const 変数名 = createContext(値);`の形でcontextを設定する
    - 今回はカウントする処理を例に記載しております
``` typescript
import { createContext } from "react";

// Contextの型を定義
interface CounterContextType {
  count: number;
  increment: () => void;
  decrement: () => void;
  reset: () => void;
}

// Contextを作成（初期値は `undefined` にしてエラーハンドリングを行う）
const CounterContext = createContext<CounterContextType | undefined>(undefined);

export default CounterContext;
```
- providerを作成する。
``` typescript
import React, { useState } from "react";
import CounterContext from "./CounterContext";

// Propsの型を定義
interface CounterProviderProps {
  children: React.ReactNode;
}

const CounterProvider: React.FC<CounterProviderProps> = ({ children }) => {
  const [count, setCount] = useState<number>(0);

  // カウントを増やす
  const increment = () => setCount((prev) => prev + 1);

  // カウントを減らす
  const decrement = () => setCount((prev) => prev - 1);

  // カウントをリセット
  const reset = () => setCount(0);

  return (
    <CounterContext.Provider value={{ count, increment, decrement, reset }}>
      {children}
    </CounterContext.Provider>
  );
};

export default CounterProvider;

```
- usecontextを使ってデータを取得
``` typescript
import React, { useContext } from "react";
import CounterContext from "./CounterContext";

const CounterDisplay: React.FC = () => {
  const context = useContext(CounterContext);

  // Contextがない場合のエラーハンドリング
  if (!context) {
    throw new Error("CounterDisplay must be used within a CounterProvider");
  }

  const { count, increment, decrement, reset } = context;

  return (
    <div style={{ textAlign: "center", padding: "20px" }}>
      <h1>カウント: {count}</h1>
      <button onClick={increment}>増やす +</button>
      <button onClick={decrement}>減らす -</button>
      <button onClick={reset}>リセット</button>
    </div>
  );
};

export default CounterDisplay;

```
- App.tsxにproviderを指定する
``` typescript
import React from "react";
import ReactDOM from "react-dom";
import CounterProvider from "./CounterProvider";
import CounterDisplay from "./CounterDisplay";

const App: React.FC = () => {
  return (
    <CounterProvider>
      <CounterDisplay />
    </CounterProvider>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
```

:::note info
実際の動作
:::

https://codesandbox.io/embed/s3gkx2?view=editor+%2B+preview&module=%2Fsrc%2FApp.tsx&hidenavigation=1


### 参考
usecontextだけだと状態管理が複雑になるので、大規模開発の場合はReduxやRecoilを使用するのがよい。

# 3.useMemo
### useMemoとは
> useMemo は、レンダー間で計算結果をキャッシュするための React フックです。

https://ja.react.dev/reference/react/useMemo

### 特徴
- 計算コストの高い処理をメモ化（キャッシュ）し、不要な再計算を防ぐ
- 値を返す（関数ではなく計算結果をキャッシュする）
- 依存配列の値が変わったときだけ再計算される

### 使用方法
基本構文は以下
第一引数：更新がかかった際に実行したい処理を記載する(計算処理, stateの更新 etc...)
第二引数：依存配列で、指定の値に更新がかかった時のみ処理が走る
``` typescript
const memoizedValue = useMemo(() => abを更新する処理等, [a, b]);
```

:::note info
実際の動作
:::
* stateのnumを2乗した値をmemoに保存する処理

https://codesandbox.io/embed/73xm4g?view=editor+%2B+preview&hidenavigation=1

### 参考
useEffectとの使い分け

|フック| 目的	|実行タイミング|	返すもの|
|:-----------:|:------------:|:------------:|:------------:|
|useMemo|計算結果をキャッシュ|	レンダリング中 に実行|	値（計算結果)|
useEffect|	副作用処理（API通信・DOM操作）|	レンダリング後 に実行|	関数（クリーンアップ処理）|


# 4.useRef
### useRefとは
> useRef は、レンダー時には不要な値を参照するための React フックです。

https://ja.react.dev/reference/react/useRef

### 特徴
- DOM 要素へのアクセスを管理
- 再レンダリングを発生させずに値を保持
- current プロパティを持ち、値を更新できる
- コンポーネントが再レンダリングされても、値がリセットされない

### 使用方法
基本構文
- `initialValue`（初期値）は null や undefined、数値、オブジェクトなど
- `ref.current` で 値にアクセス可能
- 値を変更しても再レンダリングは発生しない
``` typescript
const ref = useRef(initialValue);
```

:::note info
実際の動作
:::
* アニメーションを変更する処理
    * このパターンで、usestateを使用してしまうと不要な再レンダリングが走ってしまう
        * コンポーネントが再度更新される
    * アニメーションや UI 更新を最適化したい場合にuserefはより良い選択肢
        * ボタンを押しても、React は無駄な再描画をしない
        * 状態管理をstateで行う必要がない

https://codesandbox.io/embed/xx2wmd?view=editor+%2B+preview&module=%2Fsrc%2FAnimatedBox.tsx&hidenavigation=1