3 モックデータとの連携 フロントエンドで動作確認しながら実APIに移行する準備を整える 4 実APIとの接続実装 SWR/React QueryなどのデータフェッチングライブラリでAPI連携を実装 Figmaでのデータ戦略 データ構造の可視化 コンポーネントバリアントに代表的なデータパ ターンを設定 データ読み込み中/エラー状態も含めたUI設計 型情報の共有 プロパティ命名でAPIレスポンス構造を反映 Figma変数でデータ型やフォーマットを示唆 お勧めのAPI連携ライブラリ SWR Next.js公式推奨のデータ取得ライブラリ React React Query 柔軟なキャッシュと状態管理 RTK Query Redux Toolkitの一部として提供 実装コード例 型定義 (types.ts) Figmaのコンポーネントプロパティから生成 export interface Product { id: string; name: string; description: string; price: number; imageUrl: string; category: string; inStock: boolean; rating?: number; } export interface ApiResponse<T> { data: T; status: number; message: string; } export interface ProductsResponse { products: Product[]; total: number; page: number; limit: number; } SWR APIフック実装 useProducts.ts コンポーネントでの連携実装 ProductList.tsx import React from 'react'; import { useProducts } from '../hooks/useProducts'; import { ProductCard } from './ProductCard'; // MCPで生成したコンポーネント interface ProductListProps { category?: string; } export const ProductList: React.FC<ProductListProps> = ({ category }) => { const { products, isLoading, isError } = useProducts(category); if (isLoading) { return ( <div className="grid place-items-center h-60"> <div className="animate-spin h-10 w-10 border-4 border-purple-500 rounded-full border-t-transparent" /> div> ); } if (isError) { return ( <div className="bg-red-50 p-4 rounded-lg text-red-600"> データの取得に失敗しました。再試行してください。 div> ); } return ( <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> {products.map(product => ( <ProductCard key={product.id} id={product.id} title={product.name} description={product.description} price={product.price} imageUrl={product.imageUrl} isNew={!product.inStock} onAddToCart={(id) => console.log(`Adding ${id} to cart`)} /> ))} div> ); }; モックAPIでの開発効率化 Next.jsのAPI Routesを使ったモックAPIの実装例: // pages/api/products.ts import type { NextApiRequest, NextApiResponse } from 'next'; import { ProductsResponse, ApiResponse } from '../../types'; import mockProducts from '../../mock/products.json'; // Figmaから構造生成 export default function handler( req: NextApiRequest, res: NextApiResponse<ApiResponse<ProductsResponse>> ) { const { category, page = '1', limit = '10' } = req.query; const filteredProducts = category ? mockProducts.filter(p => p.category === category) : mockProducts; res.status(200).json({ data: { products: filteredProducts.slice( (parseInt(page as string) - 1) * parseInt(limit as string), parseInt(page as string) * parseInt(limit as string) ), total: filteredProducts.length, page: parseInt(page as string), limit: parseInt(limit as string) }, status: 200, message: 'Success' }); } import useSWR from 'swr'; import { Product, ApiResponse, ProductsResponse } from '../types'; const fetcher = async (url: string) => { const response = await fetch(url); if (!response.ok) { throw new Error('API error'); } return response.json() as Promise<ApiResponse<ProductsResponse>>; }; export function useProducts( category?: string, page: number = 1, limit: number = 10 ) { const { data, error, isLoading, mutate } = useSWR( `/api/products?category=${category || ''}&page=${page}&limit=${limit}`, fetcher ); return { products: data?.data.products || [], total: data?.data.total || 0, isLoading, isError: error, mutate }; } FigmaのMCPを活用したNext.js with TypeScriptの爆速実装ガイド 7 / 8