
はじめに:同じことを2回書く違和感
Next.js ブログに、PC 用の横並びナビゲーションと、スマートフォン用のハンバーガーメニュー(ドロップダウン)を実装していたときのことです。
最初は、サイトの構造を考えるままに、PC 用のブロックとスマホ用のブロックそれぞれに、メニュー項目(HOME、Next.js、Tech... など)を一つずつ手作業で書き込んでいました。
しかし、リンクが7つに増えたあたりで、強烈な違和感を覚えました。 PC 用に7個、スマホ用に7個、合計14個の全く同じリンク先とラベルのコードが、1つのファイル内に存在することになったからです。
「もし新しく『Contact』を追加したくなったら、2箇所を探して書き足さなきゃいけないのか?」
プログラミングの世界で「同じことを2回書くのは良くない」とよく耳にしますが、その理由が自分の手を動かしてみて初めて、リアルな問題として立ち上がってきました。
重複が引き起こす「修正漏れ」というバグ
同じ情報が複数の場所に存在すると何が困るのか。 それはコードが長くなって読みにくいから、だけではありませんでした。最大の問題は 「修正漏れ」によるバグが起きやすくなること です。
例えば、「Tech」というカテゴリー名を「Technology」に変更しようとしたとします。 PC 用のメニューは直したけれど、スマホ用のメニューを直し忘れてしまった。これだけで、アクセスする端末によってメニュー名が違うという不具合(バグ)の完成です。
コードを管理していく上で、人間の記憶力や注意力に頼る設計は非常に危険だと気づきました。
配列(データ)と表示を分離する
そこで、チュートリアルなどで見かけて「なんとなく」使っていた、データを配列にまとめる書き方を実践してみることにしました。
まず、メニューの「データ」だけを navLinks という名前のリスト(配列)として、ファイルの上のほうに1箇所だけ定義します。
tsxconst navLinks = [ { href: '/', label: 'HOME' }, { href: '/category/nextjs', label: 'Next.js' }, { href: '/category/tech', label: 'Tech' }, { href: '/category/notes', label: 'Notes' }, { href: '/about', label: 'About' }, { href: '[https://lifework-blog.com](https://lifework-blog.com)', label: 'LIFEWORK Blog', external: true }, { href: '/contact', label: 'お問い合わせ' }, ];
.map() でデータを画面に展開する
そして、実際にメニューを表示する場所(PC用、スマホ用それぞれ)では、この navLinks のデータを .map() という処理を使って展開するように書き換えました。
TypeScript
{navLinks.map((link) => (
<NavLink key={link.href} {...link} />
))}
.map() の詳しい仕組み(JavaScript の文法)は完全には理解しきれていない部分もありますが、要するに 「 navLinks という引き出しからデータを1件ずつ取り出して、画面の部品( <NavLink> )に変換して並べてくれる機能」 だと理解しました。
おわりに:設計の意図が腑に落ちた
この形にしておけば、今後メニューを増やしたり、リンク先を変更したくなったときは、一番上の navLinks の中身を1箇所だけいじれば済みます。 PC 用もスマホ用も同じデータを参照しているため、自動的に両方に反映され、「修正漏れ」は構造上絶対に起きません。
「コードの重複をなくす」というのは、単に見た目をスッキリさせるためのプログラマーの美学ではなく、 「人間がミスをしないための安全な設計」 の話だったのだと、今回の実装を通して深く腑に落ちました。 非エンジニアにとって、こういう「なぜそう書くのか」の理由が見えた瞬間は、とてもスッキリしますね。
メインブログでは、実装の手順を詳しく解説しています。





