[React] 반응형 헤더 만들기(useState, React Router, styled components)

seul·2022년 7월 22일
0

React

목록 보기
2/3
post-custom-banner

🎨 구현 목표

  • 미디어쿼리@media 공부한 후 복습
  • styled components에 익숙해지기
  • React Router 라이브러리 사용해서 페이지 라우팅까지 구현해보기

미디어 쿼리 - 화면이 줄어들면 토글 버튼 나타나게 하기

styled components로 선언한 컴포넌트 안에 태블릿 가로 사이즈(768x)이하의 화면에서는 nav-menu들이 column방향으로 정렬되도록 하고, 숨겨놨던 토글 버튼이 나타나도록 했다.

  const StyledHeader = styled.header`
    /* 생략 */
  .menuToggleBtn {
    display: none;
    /* 생략 */
  }

  @media screen and (max-width: 768px) {
    flex-direction: column;
    align-items: flex-start;
    .menuToggleBtn {
      display: block;
    }
  }
`;

토글 버튼에 이벤트 달기

토글 버튼을 열고 닫고 하기 위해서 이 상태를 관리할 수 있는 isToggleOpen state를 만들어주고, false로 초기화한다. 이 state를 NavMenu 컴포넌트(ul 태그)에 props로 내려준다. 그 다음 토글 버튼에 click이벤트가 발생하면 호출할 함수를 전달하고, 여기서 isToggleOpen 상태를 변화시키는 함수를 호출한다.

const Header = () => {
  const [isToggleOpen, setIsToggleOpen] = useState(false);

  const handleToggleOpen = () => {
    setIsToggleOpen(!isToggleOpen);
  };
  return (
    <>
      <StyledHeader>
        <div className="nav_logo">
          <Link to={"/"} className="nav-logo-link">
            Logo
          </Link>
        </div>
        <NavManu isToggleOpen={isToggleOpen}>
           {/* 생략 */}
        </NavManu>
        <FaBars className="menuToggleBtn" onClick={handleToggleOpen} />
      </StyledHeader>
    </>
  );
};

export default Header;

isToggleOpen state에 따라서 메뉴를 화면에 보여주기

NavMenu 컴포넌트가 props로 내려받은 isToggleOpen이 true일때는 메뉴를 display:block 으로, false일때는 display: none으로 적용한다.

const NavManu = styled.ul`
 /*생략 */
  @media screen and (max-width: 768px) {
    display: ${(props) => (props.isToggleOpen ? "block" : "none")};
    flex-direction: column;
    align-items: center;
    width: 100%;
  }
`;

페이지 라우팅

헤더(+네비게이션바)만 간단하게 만들어보려고 했는데 Router로 페이지 이동까지 넣으면 더 좋을 것 같아서 페이지를 여러개 만들었다.

라우터 컴포넌트들을 import 해주고, App.js에 page들도 모두 import 해준다. 라우터 역할을 하는 BrowserRouter로 전체 div를 감싸주고 Route 컴포넌트로 경로와 element를 연결해준다.

  1. BrowserRouter router(라우터 역할)
  2. Routes Route route mathers(경로 매칭 역할)
  3. Link route changers(경로 변경 역할)
import { BrowserRouter, Routes, Route } from "react-router-dom";
import "./styles.css";
import Header from "./components/Header";
import Home from "./pages/Home";
import About from "./pages/About";
import Projects from "./pages/Projects";
import Til from "./pages/Til";
import Diary from "./pages/Diary";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Header />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/projects" element={<Projects />} />
          <Route path="/Til" element={<Til />} />
          <Route path="/diary" element={<Diary />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

Header.js에서 Link 컴포넌트를 임포트 하고import { Link } from "react-router-dom";
NavMenu들이 각각 해당 경로로 이동할 수 있도록 연결해준다.

 {/* 생략 */}
        <NavManu isToggleOpen={isToggleOpen}>
          <li>
            <Link to={"/about"} className="nav-menu-list">
              About
            </Link>
          </li>
          <li>
            <Link to={"/projects"} className="nav-menu-list">
              Projects
            </Link>
          </li>
          <li>
            <Link to={"/til"} className="nav-menu-list">
              TIL
            </Link>
          </li>
          <li>
            <Link to={"/diary"} className="nav-menu-list">
              Diary
            </Link>
          </li>
        </NavManu>
 {/* 생략 */}

전체 코드와 실행결과

🥲 아쉬움

  • 이번 유닛에서 반응형 웹, CSS 애니메이션, HTML5를 공부하면서 레퍼런스로 기깔나는 작품들을 많이 봐서 눈은 잔뜩 높아졌는데 내가 익숙하게 구현할 수 있는 스타일링은 별게 없어서 아쉬웠다. 그치만 많이 만들어보는 수밖에 없겠지!
  • 일단 되게 만드는 것에만 집중하느라 styled components를 잘 활용하지 못한 것 같다. 다음에 더 잘 활용해보기!
profile
Connecting dots
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 8월 21일

참고 많이 되었습니다 !!

답글 달기