つくる - データの下ごしらえ
この章でやったことを 1 つにまとめる
アロー関数、分割代入、スプレッド、map、三項演算子と、React で毎日使う記法を復習してきました。ここではそれを 1 か所に集めて、プロフィールサイトの表示用データを作ります。
第3章から先、コンポーネントは「渡されたデータをそのまま並べるだけ」の形にしていきます。そのために、生データを画面に出せる形に整える工程が要ります。この工程を先にやっておくのが、この回の目的です。
生データと表示用データ
手元にあるのは、この 2 つです。
const profile = {
name: "あおい",
title: "Web エンジニア",
bio: "動くものを作るのが好きです。JavaScript と React を勉強中です。",
};
const works = [
{ id: 1, title: "レシピ検索アプリ", category: "web", published: true, year: 2025 },
{ id: 2, title: "買い物メモツール", category: "tool", published: true, year: 2025 },
{ id: 3, title: "写真ギャラリー", category: "web", published: false, year: 2026 },
];このままでも表示はできますが、画面に出すたびに「肩書きをかっこで囲む」「西暦を付ける」「公開中か下書きかを判定する」を書くことになります。同じ加工が何度も散らばると、直すときに全部を探すはめになります。
そこで、画面に出す形をあらかじめ作っておきます。
{
heading: "あおい(Web エンジニア)",
bio: "動くものを作るのが好きです。JavaScript と React を勉強中です。",
works: [
{ id: 1, label: "レシピ検索アプリ(2025)", status: "公開中" },
{ id: 2, label: "買い物メモツール(2025)", status: "公開中" },
{ id: 3, label: "写真ギャラリー(2026)", status: "下書き" },
],
publishedCount: 2,
}こうしておけば、コンポーネント側は受け取った文字列をそのまま出すだけで済みます。
なぜ React でこれが要るのか
React の部品は、渡されたものを描くだけの単純な形にしておくほど扱いやすくなります。加工の処理と描画の処理が同じ関数に混ざると、見た目を直したいだけなのに計算を読む必要が出てきます。
この回で作る形は、そのまま第3章の props になります。heading は ProfileCard に、works の 1 件は WorkCard に渡します。works の各件に id を残しているのも意味があります。第6章で map して並べるとき、React が要素を見分けるための key にそのまま使えるからです。
実際の開発では、この加工をまとめた関数を src/data/profile.js のような別ファイルに置き、export して画面側から import します。ファイル分割は第3章で扱うので、ここでは 1 つの関数にまとめるところまでを作ります。
つまずきどころ
もとのデータを書き換えてしまわないよう気を付けてください。map は新しい配列を返すので安全ですが、works[0].label = ... のように直接足すと、生データが表示用の情報で汚れていきます。あとで作品を追加したり並べ替えたりするとき、必ず困ります。
演習
プロフィールと作品の配列から、画面に出せる表示用データを 1 つ作ります。
要件
- 分割代入でプロフィールから name と title と bio を取り出し、bio には既定値 よろしくお願いします。 を指定する
- heading は 名前(肩書き) の形にする。かっこは全角の( と )を使う
- works は
mapで作り、1 件を id と label と status の 3 つだけにする - label は タイトル(西暦)、status は三項演算子で 公開中 か 下書き にする
- publishedCount には公開中の作品の件数を入れる
- 受け取った配列とオブジェクトは書き換えない
入出力例
buildProfilePage({"bio":"動くものを作るのが好きです。","name":"あおい","title":"Web エンジニア"}, [{"category":"web","id":1,"published":true,"title":"レシピ検索アプリ","year":2025},{"category":"tool","id":2,"published":true,"title":"買い物メモツール","year":2025},{"category":"web","id":3,"published":false,"title":"写真ギャラリー","year":2026}]) → {"bio":"動くものを作るのが好きです。","heading":"あおい(Web エンジニア)","publishedCount":2,"works":[{"id":1,"label":"レシピ検索アプリ(2025)","status":"公開中"},{"id":2,"label":"買い物メモツール(2025)","status":"公開中"},{"id":3,"label":"写真ギャラリー(2026)","status":"下書き"}]}
buildProfilePage({"name":"あおい","title":"フロントエンド担当"}, [{"category":"web","id":1,"published":true,"title":"レシピ検索アプリ","year":2025}]) → {"bio":"よろしくお願いします。","heading":"あおい(フロントエンド担当)","publishedCount":1,"works":[{"id":1,"label":"レシピ検索アプリ(2025)","status":"公開中"}]}
buildProfilePage({"bio":"これから作品を増やします。","name":"あおい","title":"Web エンジニア"}, []) → {"bio":"これから作品を増やします。","heading":"あおい(Web エンジニア)","publishedCount":0,"works":[]}
buildProfilePage({"bio":"準備中です。","name":"あおい","title":"Web エンジニア"}, [{"category":"web","id":3,"published":false,"title":"写真ギャラリー","year":2026},{"category":"tool","id":4,"published":false,"title":"読書メモアプリ","year":2026}]) → {"bio":"準備中です。","heading":"あおい(Web エンジニア)","publishedCount":0,"works":[{"id":3,"label":"写真ギャラリー(2026)","status":"下書き"},{"id":4,"label":"読書メモアプリ(2026)","status":"下書き"}]}