react-portfolio : navbar만들기(header)

임하나·2023년 2월 27일
0

react-portfolio

목록 보기
4/13


header를 만들어서 넣어줘서 각각 해당 링크에 가도록 만들어줄꺼예요.

Navbar.jsx파일을 생성해줍니다.
모든페이지에 동일하게 쓰일 것임으로, component 폴더에 만들어줍니다.

Navbar.jsx

import {Link, NavLink} from 'react-router-dom';

import './navbar.css';
import Logo from '../images/logo.png';

const Navbar = () => {
  return(
    <nav>
      <div className="container nav__container">
        <Link to="/" className="logo">
          <img src={Logo} alt="Nav logo"/>
        </Link>        
      </div>
    </nav>
  )
}
export default Navbar;

하나하나 살펴봅시다.

import {Link, NavLink} from 'react-router-dom';

이전에 이야기했던 것처럼 페이지이동을 해야하기때문에 react-router-dom을 설치해주었습니다.

<Link to="/" className="logo">
  <img src={Logo} alt="Nav logo"/>
</Link>      

Link 는 특정 주소를 넘어갈수 있게해줍니다.
위에 사용한 / 기본페이지 즉 index페이지로 이동되게되는 것입니다(home) 리액트에서는 a링크 이외에 Link태그를 사용해줍니다. a링크는 보통 새창으로 넘어갈때 쓰여집니다.

그리고 위에 쓰진 않았는데 images폴더를 만들어 이미지들을 미리 추가해주었습니다.

import Logo from '../images/logo.png'; 
<img src={Logo} alt="Nav logo"/>

App.js

import { BrowserRouter, Routes, Route } from 'react-router-dom';

import Navbar from './components/Navbar.jsx';

function App() {
  return (
    <BrowserRouter>
      <Navbar/>
      <Home/>
      <About/>
      <Gallery/>
      <Plans/>
      <Trainers/>
      <Contact/>
      <NotFound/>
    </BrowserRouter>
  );
}

BrowserRouter, Routes, Route

라우팅 할 컴포넌트(이동)들을 BrowserRouter르 감싸고 Route로 컴포넌트 별로 원하는 URL 주소를 할당합니다.

실행화면


li 태그에 링크를 걸어서 페이지를 이동해보자

Navbar.js

import {links} from '../data';

const Navbar = () => { 
  return (
    <ul className="nav__links">
            {
              links.map(({name, path}, index)=>{
                return(
                  <li key={index}>
                    <NavLink to={path}>{name}</NavLink>
                  </li>
                )
              })
            }
        </ul>
  );
}

코드분석

import {links} from '../data';

data.js에서 link의 값을 가져온다.
각페이지의 주소와 이름이 배열안에 객체로 넣어져있다.
참고로 export default 를 써주면 한번만 호출하여 쓰일 수 있고, 하단 data.js 에서 default 를 안주고 export 만 사용할경우에는 여러번 사용할 수 있다.

data.js

export const links = [
  {
    name: "Home",
    path: '/'
  },
  {
      name: "About",
      path: '/about'
  },
  {
      name: "Gallery",
      path: '/gallery'
  },
  {
      name: "Plans",
      path: '/plans'
      
  },
  {
      name: "Trainers",
      path: '/trainers'
  },
  {
      name: "Contact",
      path: '/contact'
  }
]

<ul className="nav__links">
  {
  links.map(({name, path}, index)=>{
    return(
      <li key={index}>
        <NavLink to={path}>{name}</NavLink>
      </li>
  	)
  	})
  }
  </ul>

map함수를 이용해 li의 태그 안에 links 값을 넣어준다.
name,path를 가져오고, index값을 가지고 온다.
index값은 key값으로 사용되는데, 각 고유의 키값이 필요함으로 보통 index 값으로 많이 준다.

실행화면


햄버거버튼 만들기 react-icons

import {GoThreeBars} from 'react-icons/go';

const Navbar = () => { 
  return(
    <button className="nav__toggle-btn">
    	<GoThreeBars/>
    </button>
 )
}

실행화면

https://react-icons.github.io/react-icons/
위 사이트에서 검색하여 원하는 아이콘을 찾아서 import 시키면된됩니다.
(css작업은 생략하도로 하겠습니다.)


<li key={index}>
  <NavLink to={path} className={({isActive})=> isActive ? 'active-nav' : ''}>{name}</NavLink>
</li>

코드분석

해당 NavLink 클릭 시 'isActive'가 맞다면, 클래스 'active-nav' 넣어주고, 아니라면 ''빈 값을 넣어준다


햄버거 버튼 클릭 시 nav메뉴 노출

import {useState} from 'react';
import {MdOutlineClose} from 'react-icons/md';
const Navbar = () => { 
  const [isNavShowing, setIsNavShowing] = useState(false);
  return(
    <nav>
      <div className="container nav__container">
        <Link to="/" className="logo">
          <img src={Logo} alt="Nav logo"/>
        </Link>   
        <ul className={`nav__links ${isNavShowing ? 'show__nav' : 'hide__Nav'}`}>
            {
              links.map(({name, path}, index)=>{
                return(
                  <li key={index}>
                    <NavLink to={path} className={({isActive})=> isActive ? 'active-nav' : ''}>{name}</NavLink>
                  </li>
                )
              })
            }
        </ul>
        <button className="nav__toggle-btn" onClick={()=>setIsNavShowing(!isNavShowing)}>
          {
            isNavShowing ? <MdOutlineClose/> : <GoThreeBars/>
          }
          
        </button>
      </div>
    </nav>
  )
}

코드분석

const [isNavShowing, setIsNavShowing] = useState(false);

<button className="nav__toggle-btn" onClick={()=>setIsNavShowing(!isNavShowing)}>
          {
            isNavShowing ? <MdOutlineClose/> : <GoThreeBars/>
          }
          
        </button>

상태변화값 isNavShowing 값은 false가 기본값이 되게 만들어준다.
navtoggle-btn 클릭 시, isNavShowing true 라면 (X 아이콘), false라면 (햄버거버튼)
그리고 상단 nav
links 클래스의 값도 변경된다. true라면 shownav false라면 hideNav

Header.jsx 파일을 컴포넌트에 생성해주고, Navbar 를 import 해준다음, home.jsx에서 Header를 import해줍니다.
그런데 이럴경우 isNavShowing 의 상태값이 제대로 전달되지않는다고합니다.....(저는 잘됐어요.) 그래서 만약에 안될경우.

<button className="nav__toggle-btn" onClick={()=>setIsNavShowing(prev => !prev)}>
  {
  isNavShowing ? <MdOutlineClose/> : <GoThreeBars/>
}
</button>

기존에 setIsNavShowing(!isNavShowing) 이런 식으로 쓴 경우를 위와 같이 바꿔줍니다. 바로 이전 값을 반대로 바꿔준다는 뜻이죠.


로고 클릭시, nav리스트 닫기

<Link to="/" className="logo" onClick={()=>setIsNavShowing(false)}>
  <img src={Logo} alt="Nav logo"/>
    </Link>   

setIsNavShowing 상태변화값을 false로만 만들어주면됩니다.


App.js

import { BrowserRouter, Routes, Route } from 'react-router-dom';

import About from './pages/about/About.jsx';
import Home from './pages/home/Home.jsx';
import Gallery from './pages/gallery/Gallery.jsx';
import Plans from './pages/plans/Plans.jsx';
import Trainers from './pages/trainers/Trainers.jsx';
import Contact from './pages/contact/Contact.jsx';
import NotFound from './pages/notFound/NotFound.jsx';
import Navbar from './components/Navbar.jsx';

function App() {
  return (
    <BrowserRouter>
      <Navbar/>
      <Routes>
        <Route index element={<Home/>} />
        <Route path='about' element={<About/>} />
        <Route path='contact' element={<Contact/>} />
        <Route path='gallery' element={<Gallery/>} />
        <Route path='plans' element={<Plans/>} />
        <Route path='trainers' element={<Trainers/>} />
        <Route path='*' element={<NotFound/>} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;


nav리스트 클릭 시 해당 파일로 이동되며, 화면에 노출이 됩니다.

0개의 댓글