React(Next.js)の開発の覚書
初めてReact案件に入ったので覚書
React Hooks
useState
const [data, setData] = useState<Data[]>([]); //引数は初期値
メモ: dataにはデータのポインタ(メモリのアドレス)が入っていて、実際のデータはsetDataされるごとに新規作成されて、dataのポインタを更新してる。
useEffect
useEffect(() => {
console.log('dataが変更されました:', count);
}, [依存1, 依存2, 依存3...]); // 依存配列の監視対象の値が変わるたびに実行される。
useEffect(() => {
console.log('dataが変更されました:', count);
}, []); // 依存配列に空配列を指定すると、初回マウント時に1度だけ実行される。
メモ: 副作用を記述に使う。Aが変更された時に、非同期でBの処理が実行される。第一引数: 処理(B)、第二引数: 依存配列([A])。
useContext
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
の定義です。
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
メッセージを表示するコンポーネントの定義です。
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
アプリケーションのルートコンポーネントの定義です。
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のディレクトリ例
├── 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
追々