Reactのコーポレートサイトにニュースページを追加する

投稿日:2024年09月17日

更新日:2024年09月17日

投稿者:HIROKI CHIYODA

はじめに

前回の記事で作成したコーポレートサイトにニュースページを作成します。

Next.jsでは、App Routerが標準で設定する必要はありません。
同じように、Reactでも、ルーティングを使って、複数ページを管理します。
ただ、React自体には、App Routerと同様な機能は、標準ではありません。
そこで、React Routerを導入するがあります。

React Router DOMをインストール

bun add react-router-dom

routerを追加

routerの設定を追加して、パスにトップページを追加

  import React from "react";
  import ReactDOM from "react-dom/client";
+ import { createBrowserRouter, RouterProvider } from "react-router-dom";
  import App from "./App";
  import "./index.css";

+ const router = createBrowserRouter([
+   {
+     path: "/",
+     element: <App />,
+   },
+ ]);

  ReactDOM.createRoot(document.getElementById("root")!).render(
    <React.StrictMode>
-  	  <App />
+ 		<RouterProvider router={router} />
    </React.StrictMode>
  );

ニュースページを仮作成

news-page.tsxを仮作成
ヘッダーを追加

import Header from "./components/header";

export default function NewsPage() {
  return (
    <>
      <Header />
      <main className="max-w-5xl mx-auto mt-20">NewsPage</main>
    </>
  );
}

routerにニュースページのパスを追加

  import React from "react";
  import ReactDOM from "react-dom/client";
  import { createBrowserRouter, RouterProvider } from "react-router-dom";
  import App from "./App";
  import "./index.css";
+ import NewsPage from "./news-page";

  const router = createBrowserRouter([
    {
      path: "/",
      element: <App />,
    },
+   {
+     path: "news",
+     element: <NewsPage />,
+   },
  ]);

  ReactDOM.createRoot(document.getElementById("root")!).render(
    <React.StrictMode>
  		<RouterProvider router={router} />
    </React.StrictMode>
  );

ヘッダーのロゴのリンクパスを変更

  <h1 className="w-48 lg:flex justify-end items-end pl-4">
-   <a href="#">
+   <a href="/">
    	<img src="/logo.svg" alt="logo" width="100" height="100" />
    </a>
  </h1>

また、ヘッダーのニュースのリンクパスを変更


  <li className="p-4">
-   <MenuLink href="#">NEWS</MenuLink>
+   <MenuLink href="/news">NEWS</MenuLink>
  </li>

ニュースページを作成

tailwind-mergeをインストール

bun add tailwind-merge

news-content.tsxを変更
lg:border-r-2 border-black last:border-r-0 lg:w-1/3を削除
twMergeを導入

+ import { twMerge } from "tailwind-merge";
  
  export default function NewsContent({
    date,
    tag,
    title,
+   className,
  }: {
    date: string;
    tag: string;
    title: string;
+   className?: string;
  }) {
    return (
-     <div className="flex flex-col justify-center first:pl-0 space-y-4 lg:border-r-2 border-black last:border-r-0 lg:w-1/3 h-20">
+     <div
+       className={twMerge(
+         `${className}`,
+         "flex flex-col justify-center first:pl-0 space-y-4 h-20"
+       )}
+     >
        <div className="flex space-x-2.5">
          <time className="text-sm font-light">{date}</time>
          <p className="flex justify-center items-center text-white text-xs font-light bg-black uppercase w-12">
            {tag}
          </p>
        </div>
        <p className="font-light">{title}</p>
      </div>
    );
  }

news.tsxを修正
削除したlg:border-r-2 border-black last:border-r-0を追加

  import NewsContent from "./ui/news-content";
  import SectionTitle from "./ui/section-title";
  
  export default function News() {
    return (
      <div id="news" className="max-w-5xl mx-auto pt-28 px-4">
        <SectionTitle title="news" subTitle="ニュース" />
        <div className="lg:flex lg:space-x-5 mt-16 space-y-10 lg:space-y-0">
          <NewsContent
            date="2022.01.01"
            tag="news"
            title="タイトルタイトルタイトルタイトル"
+           className="lg:border-r-2 border-black last:border-r-0 lg:w-1/3"
          />
          <NewsContent
            date="2022.01.01"
            tag="press"
            title="タイトルタイトルタイトルタイトル"
+           className="lg:border-r-2 border-black last:border-r-0 lg:w-1/3"
          />
          <NewsContent
            date="2022.01.01"
            tag="news"
            title="タイトルタイトルタイトルタイトル"
+           className="lg:border-r-2 border-black last:border-r-0 lg:w-1/3"
          />
        </div>
      </div>
    );
  }

news-page.tsxを作成

import Footer from "./components/footer";
import Header from "./components/header";
import NewsContent from "./components/ui/news-content";

export default function News() {
  return (
    <>
      <Header />
      <main className="max-w-5xl mx-auto lg:mt-20 lg:mb-32 px-4">
        <h2 className="text-4xl font-light uppercase tracking-[0.25em] pt-20">
          News & Press
        </h2>
        <div className="mt-24 border-b border-black">
          <button className="lg:w-60 w-1/2 font-light pb-5 border-b-2 border-black">
            ニュース
          </button>
          <button className="lg:w-60 w-1/2 font-light pb-5">
            プレスリリース
          </button>
        </div>
        <NewsContent
          date="2022.01.01"
          tag="news"
          title="タイトルタイトルタイトルタイトル"
          className="border-r-0 border-b border-black lg:w-full lg:mt-14 mt-10 lg:pb-14 pb-10"
        />
        <NewsContent
          date="2022.01.01"
          tag="news"
          title="タイトルタイトルタイトルタイトル"
          className="border-r-0 border-b border-black lg:w-full lg:mt-14 mt-10 lg:pb-14 pb-10"
        />
        <NewsContent
          date="2022.01.01"
          tag="news"
          title="タイトルタイトルタイトルタイトル"
          className="border-r-0 border-b border-black lg:w-full lg:mt-14 mt-10 lg:pb-14 pb-10"
        />
        <NewsContent
          date="2022.01.01"
          tag="news"
          title="タイトルタイトルタイトルタイトル"
          className="border-r-0 border-b border-black lg:w-full lg:mt-14 mt-10 lg:pb-14 pb-10"
        />
        <NewsContent
          date="2022.01.01"
          tag="news"
          title="タイトルタイトルタイトルタイトル"
          className="border-r-0 border-b border-black lg:w-full lg:mt-14 mt-10 lg:pb-14 pb-10"
        />
      </main>
      <Footer />
    </>
  );
}