React의 반응형 Navbar

얘들아!

제 이름은 Gustavo Scarpim입니다. 간단하고 반응이 빠른 Navbar를 만드는 방법을 알려드리겠습니다.

내비게이션 만들기



먼저 Burger라는 파일을 만들고 바로 다음에 만들 RightNav라는 구성 요소를 가져옵니다. 이 파일 안에 다음 코드를 넣습니다.

import React, { useState } from 'react';
import * as S from './styles';

import RightNav from './RightNav';

const Burger = () => {
  const [open, setOpen] = useState(false)

  return (
    <>
      <S.StyledBurger open={open} onClick={() => setOpen(!open)}>
        <div />
        <div />
        <div />
      </S.StyledBurger>
      <RightNav open={open} />
    </>
  )
}
export default Burger


그런 다음 로고를 선택한 폴더로 가져와 Navbar라는 파일을 만들거나 간단히 제거할 수 있으며 바로 위에서 만든 Burger 구성 요소도 가져옵니다.

import React from 'react';
import * as S from './styles';

import Logo from '../../assets/logo.png';
import Burger from './Burger';

type Props = {
  children?: any;
}

export default function Navbar(props: Props) {
  return (
    <>
      <S.Nav>
        <S.Logo src={Logo} alt="Etio Soluções" />
      </S.Nav>
      <Burger />
      {props.children}
    </>
  )
}


react-router-dom을 가져오고 이미지를 자산 폴더로 호출하여 RightNav라는 파일을 생성합니다.

import React from 'react'
import * as S from './styles';

import Logo from '../../assets/logo.png';
import IconReact from '../../assets/react.svg';
import IconMegamen from '../../assets/megamen.png';
import IconMario from '../../assets/mario.png';
import IconTurtle from '../../assets/turtle.png';

import { BrowserRouter as Router, Switch, Route, NavLink, Redirect } from "react-router-dom";

type Props = {
  open: boolean;
}

function RightNav(props: Props) {

  return (
    <Router>
      <S.Ul open={props.open}>
        <S.LogoUl src={Logo} alt={'Gustavo Scarpim'} />

        <NavLink to="/menu1"
          activeStyle={{
            fontWeight: "bold",
            color: "#0DADEA"
          }}
        >
          <li>Menu 1</li>
        </NavLink>
        <NavLink to="/menu2"
          activeStyle={{
            fontWeight: "bold",
            color: "#0DADEA"
          }}
        >
          <li>Menu 2</li>
        </NavLink>
        <NavLink to="/menu3"
          activeStyle={{
            fontWeight: "bold",
            color: "#0DADEA"
          }}
        >
          <li>Menu 3</li>
        </NavLink>
        <NavLink to="/menu4"
          activeStyle={{
            fontWeight: "bold",
            color: "#0DADEA"
          }}
        >
          <li>Menu 4</li>
        </NavLink>
      </S.Ul>


      <Switch>
        <Route exact path="/menu1">
          <S.Icon>
            <img src={IconReact} alt="React" />
          </S.Icon>
        </Route>
        <Route exact path="/menu2" >
          <S.Icon>
            <img src={IconMegamen} alt="Megamen" />
          </S.Icon>
        </Route>
        <Route exact path="/menu3" >
          <S.Icon>
            <img src={IconMario} alt="Mario" />
          </S.Icon>
        </Route>
        <Route exact path="/menu4" >
          <S.Icon>
            <img src={IconTurtle} alt="Turtle" />
          </S.Icon>
        </Route>

        <Redirect to='/menu1' />
      </Switch>
    </Router >
  )
}

export default RightNav


마지막으로 styled-components로 css를 생성할 것입니다. styles.ts라는 파일 안에 다음 코드를 추가하기만 하면 됩니다.

import styled from 'styled-components';

interface INav {
  open: boolean;
  href?: string;
}

export const StyledBurger = styled.div<INav>`
  width: 2rem;
  height: 2rem;
  position: fixed;
  top: 15px;
  right: 20px;
  z-index: 20;
  display: none;

  @media (max-width: 768px) {
    display: flex;
    justify-content: space-around;
    flex-flow: column nowrap;
  }
  div {
    width: 2rem;
    height: 0.25rem;
    background-color: ${(props) => props.open ? '#000' : '#000'};
    border-radius: 10px;
    transform-origin: 1px;
    transition: all 0.3s linear;
    cursor: pointer;
    &:nth-child(1) {
      transform: ${(props) => props.open ? 'rotate(45deg)' : 'rotate(0)'};
    }
    &:nth-child(2) {
      transform: ${(props) => props.open ? 'translateX(100%)' : 'translateX(0)'};
      opacity: ${(props) => props.open ? 0 : 1};
    }
    &:nth-child(3) {
      transform: ${(props) => props.open ? 'rotate(-45deg)' : 'rotate(0)'};
    }
  }
`

export const Nav = styled.nav`
  height: 100%;
  display: flex;
  justify-content: space-between;
  background-color: #fdfdfdfa;
  align-items: center;
  position: relative;

  @media (max-width: 678px) {
    width: 100vw;
  }

  span {
    font-size: 30px;
    @media only screen and (max-width: 600px) {
      font-size: 20px;
      :nth-child(2) {
        font-size: 16px !important;
        margin-top: 0px !important;
      }
    }
  }

`

export const Ul = styled.ul<INav>`
  list-style: none;
  display: flex;
  flex-flow: row nowrap;
  position: absolute;
  width: 90%;
  top: 0;
  justify-content: flex-end;
  margin-top: 0px;
  align-items: center;
  font-size: 18px;
  height: 110px;
  margin-left: 20px;

  a {
    text-decoration: none;
    text-transform: none;
    color: #000;
    cursor: pointer;

    &:hover {
      color: #0DADEA;
    }
  }

  li {
    padding: 18px 10px;
  }

  @media (max-width: 768px) {
    flex-flow: column nowrap;
    background-color: #fdfdfdfa;
    position: fixed;
    transform: ${(props) => props.open ? 'translateX(0)' : 'translateX(100%)'};
    top: -16px;
    right: 0;
    height: 100%;
    width: 180px;
    padding-top: 3.5rem;
    transition: transform 0.3s ease-in-out;
    z-index: 9;
    justify-content: normal;

    li {
      color: #000;
      margin-right: 34px;

      &:hover {
        color: #0DADEA;
      }
    }
  }
`

export const Logo = styled.img`
  margin: 20px 50px 20px 7%;
  width: 160px;
  height: 70px;
  object-fit: contain;

  @media (max-width: 1250px) {
    margin: 20px 50px 20px 5%;
  }

`

export const LogoUl = styled.img`
  margin: 20px 50px 20px 5%;
  display: none;

  @media (max-width: 768px) {
    display: flex;
    width: 160px;
    height: 70px;
    object-fit: contain;
  }
`
export const Icon = styled.div`
  width: 100vw;
  height: calc(100vh - 112px);
  display: flex;
  justify-content: center;
  align-items: center;

  img {
    width: 150px;
    height: 150px;
    pointer-events: none;
    object-fit: contain;

    @media (prefers-reduced-motion: no-preference) {
      animation: App-logo-spin infinite 20s linear;
    }
  }

    @keyframes App-logo-spin {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
  }
`


마지막으로 전체 프로젝트에서 사용할 Navbar 구성 요소의 기본 인덱스에 도달합니다.

import React from 'react';
import ReactDOM from 'react-dom';
import reportWebVitals from './reportWebVitals';
import Menu from './components/menu/Navbar';

ReactDOM.render(
  <React.StrictMode>

    <Menu />
  </React.StrictMode>,
  document.getElementById('root')
);

reportWebVitals();


그리고 준비, 메뉴 navBar가 완료되었습니다.


다음과 같이 표시됩니다(이미지 변경).



전체 코드는 여기GitHub에서 확인하세요.
Project in action을 확인하십시오.

읽어 주셔서 감사합니다.

좋은 웹페이지 즐겨찾기