React(Next.js)の開発の覚書

# React(Next.js)の開発の覚書

初めてReact案件に入ったので覚書

## React Hooks
### useState
```tsx
const [data, setData] = useState<Data[]>([]); //引数は初期値
```

メモ: dataにはデータのポインタ(メモリのアドレス)が入っていて、実際のデータはsetDataされるごとに新規作成されて、dataのポインタを更新してる。

### useEffect
```tsx
useEffect(() => {
  console.log('dataが変更されました:', count);
}, [依存1, 依存2, 依存3...]); // 依存配列の監視対象の値が変わるたびに実行される。
```

```tsx
useEffect(() => {
  console.log('dataが変更されました:', count);
}, []); // 依存配列に空配列を指定すると、初回マウント時に1度だけ実行される。
```

メモ: 副作用を記述に使う。Aが変更された時に、非同期でBの処理が実行される。第一引数: 処理(B)、第二引数: 依存配列([A])。

### useContext
```tsx
import React, { createContext, useState, ReactNode } from 'react';

interface MessageContextType {
  message: ReactNode;
  showMessage: (msg: ReactNode) => void;
}

export const MessageContext = createContext<MessageContextType | null>(null);

interface MessageProviderProps {
  children: ReactNode;
}

export const MessageProvider: React.FC<MessageProviderProps> = ({ children }) => {
  const [message, setMessage] = useState<ReactNode>(null);

  const showMessage = (msg: ReactNode) => {
    setMessage(msg);
  };

  const contextValue = {
    message,
    showMessage
  };

  return (
    <MessageContext.Provider value={contextValue}>
      {children}
    </MessageContext.Provider>
  );
};
```

### useMessage.tsx

カスタムフック `useMessage` の定義です。

```tsx
import { useContext } from 'react';
import { MessageContext, MessageContextType } from './MessageContext';

export const useMessage = () => {
  const context = useContext(MessageContext);
  if (!context) {
    throw new Error('useMessage must be used within a MessageProvider');
  }
  return context as MessageContextType;
};
```

### YourComponent.tsx

メッセージを表示するコンポーネントの定義です。

```tsx
import React from 'react';
import { useMessage } from './useMessage';

export const YourComponent: React.FC = () => {
  const { showMessage } = useMessage();

  return (
    <div>
      <button onClick={() => showMessage(<p>メッセージ</p>)}>
        Show Message
      </button>
    </div>
  );
};
```

### App.tsx

アプリケーションのルートコンポーネントの定義です。

```tsx
import React from 'react';
import { MessageProvider } from './MessageContext';
import { YourComponent } from './YourComponent';

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

export default App;
```

## Next.jsのディレクトリ例
```bash
├── public                          # 静的ファイルを格納
│   ├── icons                       # アイコンファイル
│   └── images                      # 画像ファイル
└── src                             # ソースコード
    ├── actions                     # Reduxアクションの定義
    ├── app                         # アプリケーションの主要機能やページ
    │   ├── (loggedin)              # ログイン後のユーザー専用コンテンツ ※
    │   ├── lib                     # 汎用ライブラリやヘルパー関数
    │   ├── login                   # ログイン機能関連
    │   │   └── component           # ログイン機能に関連するコンポーネント
    │   ├── function_a              # A機能関連
    │   │   ├── component           # A機能に関連するコンポーネント
    │   │   ├── a_1                 # a_1機能
    │   │   └── a_2                 # a_2機能
    │   ├── function_b              # B機能関連
    │   │   ├── component           # B機能に関連するコンポーネント
    │   │   ├── b_1                 # b_1機能
    │   │   └── b_2                 # b_2機能
    │   ├── function_c              # C機能関連
    │   │   ....続く
    │   └── test                    # テストコード
    ├── components                  # UIコンポーネント
    │   ├── atoms/                  # 最も基本的なUI要素
    │   │   ├── Button/
    │   │   ├── Icon/
    │   │   ├── Input/
    │   │   └── ...                 # その他の原子レベルのコンポーネント
    │   ├── molecules/              # 原子を組み合わせたコンポーネント
    │   │   ├── SearchBar/
    │   │   ├── UserCard/
    │   │   ├── FormField/
    │   │   └── ...                 # その他の分子レベルのコンポーネント
    │   ├── organisms/              # 分子を組み合わせたより複雑なコンポーネント
    │   │   ├── Header/
    │   │   ├── Footer/
    │   │   ├── ProductList/
    │   │   └── ...                 # その他の有機体レベルのコンポーネント
    │   └── templates/              # ページのレイアウトを定義
    │       ├── DefaultLayout/
    │       ├── BlogLayout/
    │       └── ...                 # その他のテンプレート
    ├── constants                   # 定数の定義
    ├── context                     # Reactコンテキストの定義
    ├── gql                         # GraphQLのスキーマやフラグメント
    ├── graphql                     # GraphQLクエリとミューテーション
    │   ├── mutations               # GraphQLミューテーション
    │   └── queries                 # GraphQLクエリ
    ├── hooks                       # カスタムReactフック
    ├── middleware                  # ミドルウェア関連の設定や関数
    ├── providers                   # コンテキストプロバイダー
    ├── stores                      # Reduxやその他の状態管理ストア
    ├── styles                      # スタイルシート（CSSやSASS）
    └── utils/                      # ユーティリティ関数を格納
        ├── dateConverters.ts       # 日付関連の変換関数
        ├── mathHelpers.ts          # 数学的なヘルパー関数
        └── ...                     # その他のユーティリティ関数
```

メモ: 従来のNext.jsではプロジェクトの作成時に「pages」という名称のディレクトリが作成されていました。Next.js 13でappディレクトリの機能を使用する場合、「pages」ではなく「app」という名称のディレクトリが必要です。

## 共通コンポーネント
どこに共通化したファイルを入れたらいいのかわからないのでまとめました。

### src/app/lib

- **用途**: `pages` 内で共通して使用される機能やヘルパー関数を配置します。
- **例**: 特定のページでのみ使用されるデータ取得関数やページ固有のロジック。

### src/app/functionA/component

- **用途**: 特定の機能（この例では `functionA`）に関連するコンポーネントを配置します。
- **例**: `functionA` 関連のページ部品やレイアウトコンポーネント。

### src/components/atoms

- **用途**: 最も基本的なUI要素（ボタン、ラベル、入力フィールドなど）を配置します。
- **例**: 汎用的なボタン、アイコン、ラベル。

### src/components/molecules

- **用途**: 複数の `atoms` を組み合わせたUIコンポーネントを配置します。
- **例**: フォームフィールド（ラベル + 入力フィールド）、ユーザーカード（アバター + ユーザー名 + ユーザー情報）。

### src/components/organisms

- **用途**: 複数の `molecules`（または `atoms`）を組み合わせて、より複雑なUIセクションを構築します。
- **例**: ナビゲーションバー（ロゴ + メニューアイテム）、製品リスト（製品カードの集合）。

### src/utils

- **用途**: アプリケーション全体で共通して使用されるユーティリティ関数やヘルパー関数を配置します。
- **例**: 日付のフォーマット変更、数値のフォーマット変更、APIリクエスト関数。

### 配置のポイント

- **再利用性と範囲**: `atoms`、`molecules`、`organisms` はUIコンポーネントの再利用性と範囲に基づいて配置されます。`atoms` は最も基本的で、`organisms` は最も複合的です。
- **特定の機能に焦点を当てる**: `src/app/functionA/component` のようなディレクトリは、特定の機能や機能セットに焦点を当てたコンポーネントをグループ化します。
- **共通機能とユーティリティ**: `src/app/lib` と `utils` は、機能やヘルパー関数をグループ化しますが、範囲が異なります。`src/app/lib` はページ特有の機能に対して、`utils` はアプリケーション全体に跨る機能に対して使用されます。(`src/app/lib`=`画面特有`, `utils`=`画面も画面以外の処理でも使用`)

### App router
#### 1. サーバーコンポーネント
Secureな処理(クライアントで実行させたくない処理)、Data Fetchならサーバーコンポーネント
ex) 認証系、apiの実行、時刻の取得など
'server-only'オプションを使用することで明示的にサーバーのみの実行に指定できる
#### 2. クライアントコンポーネント
stateの管理が必要ならクライアントコンポーネント
### atomic desine
#### 1. atom, molecules
サーバーコンポーネント(データ取得, stateを使わない)
#### 2. それ以外
一般的な定義で
### graphqlについて
追々
### redux
追々
### recoil
追々
### storybook
追々
### playwright
追々