全セクションReact化

残っているのは2つだけ

ここまでの8章で、プロフィールサイトの主役はすべて React になりました。プロフィールカード、ダークモード、お問い合わせフォーム、作品ギャラリー、ヘッダーの時計です。まだ JavaScript のまま残っているのは、スキル一覧とフッターの2つだけです。この回で残りを片づけて、サイト全体を React にします。

移植の手順はいつも同じ

どのセクションでも、やることは次の4つです。ここまで無意識にやってきた流れを、言葉にしておきます。

  1. 元の HTML を見て、同じ形が繰り返されているところを探す
  2. 繰り返しの中で「変わる値」だけを取り出して配列にする
  3. 1件ぶんの見た目を返すコンポーネントを書く
  4. 配列を map でまわして並べる

スキル一覧は、まさにこの形をしています。「スキル名」と「習熟度」の2つだけが変わり、あとは同じ見た目の繰り返しです。

コードで見る

まずデータを別ファイルに置きます。表示のコードとデータが混ざっていると、スキルを1つ足すだけで見た目のコードを触ることになるからです。

// data.js export const skills = [ { name: "HTML", level: "得意" }, { name: "React", level: "学習中" }, ];

受け取る側は、配列を props でもらって map で並べるだけです。

export default function SkillList({ skills }) { return ( <ul className="skill-list"> {skills.map((skill) => ( <li key={skill.name}> {skill.name}{skill.level} </li> ))} </ul> ); }

スキル名は重複しないので、key にそのまま使えます。key に配列の添え字を使わない理由は第6章のとおりです。

フッターは props で受ける

フッターは繰り返しがないので map は要りません。ただし年や名前を直書きすると、あとで直す場所が増えます。呼び出す側から props で渡す形にしておきます。

export default function Footer({ name, year }) { return ( <footer> <p> {year} {name} </p> </footer> ); }

つまずきどころ

別ファイルのコンポーネントを読み込むとき、パスの書き方を間違えると画面が真っ白になります。同じフォルダにあるファイルは ./SkillList.jsx のように先頭にドットとスラッシュを付けます。拡張子まで書くのが確実です。

もう1つは props の名前です。渡す側が skills なら受け取る側も skills で分割代入します。片方だけ skillList のように変えると、中身が undefined になって map のところで落ちます。

演習

まだ中身が空のままの SkillList と Footer を完成させて、サイトの全セクションを React にします。

ヒント

App.jsx
Footer.jsx
SkillList.jsx
data.js
App.jsx
Footer.jsx
SkillList.jsx
data.js
プレビュー

できているか

  • スキルが4件表示されている
  • li が ul の中に入っている
  • スキル一覧に習熟度も表示されている
  • footer に名前が表示されている