[React] 19. スクロールに切り替えるページの作成


今日は、単一ページでスクロールを使用して切り替える方法について説明します.styled-componentでスタイリングをしました.
次のように、3つの主要コンポーネントを作成してページを整理しました.
Header-ナビゲーション構成
コンテンツ-ページの内容を整理
ホームページとコンテンツページ

🔥 ヘッドの作成

ulおよびliaのラベルからなる.handleClickMenu関数では、scrollIntoView構成を使用してidを有する要素の位置にスクロールする.

👉 ScrollIntoView()


該当する場所へスクロール
behavor:スムーズな移動を実現するために[スムーズ](Smooth)を追加
import React from "react";
import styled from "styled-components";
const Header = () => {
  const handleClickMenu = (e) => {
    e.preventDefault();
    if (e.target.classList.contains("menu-item")) {
      const id = e.target.getAttribute("href");
      document.querySelector(id).scrollIntoView({
        behavior: "smooth",
      });
    }
  };

  return (
    <div>
      <Menu onClick={handleClickMenu}>
        <MenuItem>
          <Link href="#home" className="menu-item">
            HOME
          </Link>
        </MenuItem>
        <MenuItem>
          <Link href="#profile" className="menu-item">
            PROFILE
          </Link>
        </MenuItem>
        <MenuItem>
          <Link href="#project" className="menu-item">
            PROJECT
          </Link>
        </MenuItem>
        <MenuItem>
          <Link href="#contact" className="menu-item">
            CONTACT
          </Link>
        </MenuItem>
      </Menu>
    </div>
  );
};

export default Header;

const Menu = styled.ul`
  display: flex;
  flex-direction: row;
  width: 50%;
  height: 54px;
  padding: 0px;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 0px;
  right: 50%;
  transform: translateX(50%);
`;

const MenuItem = styled.li`
  margin: 0px 32px;
  list-style: none;
`;

const Link = styled.a`
  font-size: 16px;
  text-decoration: none;
  color: #333;
  font-weight: bold;
  padding: 12px;
  border-radius: 20px;

  &:hover {
    background-color: #438ecc;
    color: #fff;
  }
`;

コンテンツの作成

Contentsは、ページを構成するコンポーネントであり、各コンポーネントはidで区切られている.<Header />でクリックしたアイテムIDに一致する領域にスクロールします.
import React from "react";
import styled from "styled-components";
import Home from "./contents/Home";
import Profile from "./contents/Profile";
import Project from "./contents/Project";
import Contact from "./contents/Contact";

const Contents = () => (
  <Container>
    <ContentsWrapper id="home" bgColor="#d4ecff">
      <Home />
    </ContentsWrapper>
    <ContentsWrapper id="profile">
      <Profile />
    </ContentsWrapper>
    <ContentsWrapper id="project" bgColor="#d4ecff">
      <Project />
    </ContentsWrapper>
    <ContentsWrapper id="contact" bgColor="#133f63">
      <Contact />
    </ContentsWrapper>
  </Container>
);

export default Contents;
const Container = styled.div`
  display: flex;
  width: 100vw;
  flex-direction: column;
  align-items: center;
  margin-top: 80px;
`;

const ContentsWrapper = styled.div`
  width: 100%;
  height: 100vh;
  background-color: ${(props) => (props.bgColor ? props.bgColor : "#fff")};
`;

Mainの作成

<Header /><Contents />を組み込むために、Mainという要素を追加しました.
/* event Delegation을 사용한 nav 구현 */
import React from "react";
import styled from "styled-components";
import Contents from "./contents";
import Header from "./header";
const Main = () => {
  return (
    <Container>
      <Header />
      <Contents />
    </Container>
  );
};

export default Main;

const Container = styled.div`
  display: flex;
  width: 100vw;
  flex-direction: column;
  align-items: center;
  position: relative;
`;

次に、最終的に作成された構成部品をApp構成部品に追加する.さらに上に移動するためのボタンを作成しました.
import React from "react";
import Contents from "./scorllPage/index";
import styled from "styled-components";
import { FaRegArrowAltCircleUp } from "react-icons/fa";

const App = () => {
   const handleScrollToTop = () => {
    window.scrollTo({
      top: 0,
      behavior: "smooth",
    });
  };
  return (
    <Container>
      <Button size="36px" color="#767676" onClick={handleScrollToTop} />
	  <ScrollPage />
    </Container>
  );
};

const Container = styled.div`
  position: relative;
`;
const Button = styled(FaRegArrowAltCircleUp)`
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 1000;
  outline: none;
`;