モダンフロントエンド開発の実践ガイド
2024-02-04
モダンフロントエンド開発の実践ガイド
現代のフロントエンド開発において重要な技術とプラクティスについて、実践的な例を交えて解説します。
1. コンポーネント設計
アトミックデザイン
UIコンポーネントを階層的に整理する手法です。
// Atoms(最小単位のコンポーネント)
const Button = ({ children, onClick }) => (
<button
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
onClick={onClick}
>
{children}
</button>
)
// Molecules(複数のAtomsを組み合わせたコンポーネント)
const SearchBar = () => (
<div className="flex gap-2">
<input
type="text"
className="px-3 py-2 border rounded"
placeholder="検索..."
/>
<Button>検索</Button>
</div>
)
// Organisms(複雑な機能を持つコンポーネント)
const Header = () => (
<header className="flex justify-between items-center p-4">
<Logo />
<SearchBar />
<Navigation />
</header>
)
2. 状態管理
Reactの状態管理パターン
// ローカル状態
const Counter = () => {
const [count, setCount] = useState(0)
return (
<div>
<p>カウント: {count}</p>
<Button onClick={() => setCount(count + 1)}>
増やす
</Button>
</div>
)
}
// グローバル状態(Zustand使用例)
import create from 'zustand'
const useStore = create((set) => ({
user: null,
setUser: (user) => set({ user }),
logout: () => set({ user: null }),
}))
const UserProfile = () => {
const user = useStore((state) => state.user)
const logout = useStore((state) => state.logout)
if (!user) return <LoginForm />
return (
<div>
<h2>{user.name}さん</h2>
<Button onClick={logout}>ログアウト</Button>
</div>
)
}
3. パフォーマンス最適化
メモ化とコード分割
// メモ化されたコンポーネント
const ExpensiveComponent = memo(({ data }) => {
// 重い処理を行うコンポーネント
return <div>{/* 複雑なレンダリング */}</div>
})
// 動的インポート
const DynamicChart = dynamic(() => import('./Chart'), {
loading: () => <LoadingSpinner />,
ssr: false,
})
4. アクセシビリティ
アクセシブルなコンポーネント
// アクセシブルなモーダル
const Modal = ({ isOpen, onClose, title, children }) => {
const modalRef = useRef(null)
useEffect(() => {
if (isOpen) {
modalRef.current?.focus()
}
}, [isOpen])
return (
<dialog
ref={modalRef}
open={isOpen}
className="p-6 rounded-lg shadow-xl"
aria-labelledby="modal-title"
>
<h2 id="modal-title" className="text-xl font-bold mb-4">
{title}
</h2>
{children}
<button
onClick={onClose}
aria-label="閉じる"
className="absolute top-2 right-2"
>
×
</button>
</dialog>
)
}
5. テスト駆動開発
コンポーネントのテスト
// Jestとテスティングライブラリを使用したテスト
describe('Button', () => {
it('クリックイベントが発火する', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick}>テスト</Button>)
fireEvent.click(screen.getByText('テスト'))
expect(handleClick).toHaveBeenCalled()
})
it('無効化状態が正しく反映される', () => {
render(<Button disabled>テスト</Button>)
expect(screen.getByText('テスト')).toBeDisabled()
})
})
フロントエンド開発のベストプラクティス
-
コンポーネントの責務
- 単一責任の原則に従う
- プロップスは明確に型定義
- 副作用は最小限に
-
パフォーマンス
- 適切なメモ化
- 遅延読み込みの活用
- バンドルサイズの最適化
-
保守性
- 一貫性のあるコーディング規約
- 適切なドキュメント
- 効果的なエラーハンドリング
フロントエンド開発は常に進化しています。新しい技術やツールを取り入れながら、基本的な原則を守ることが重要です。