FE/React

[리액트 실습] 마켓컬리 클론코딩 1. 헤더 만들기

개발새발주발 2023. 2. 3. 18:35
728x90

3주차 과제는 ~~~ 

마켓컬리 클론 코딩이다 ! 

 

3주차에서는 SPA, routing에 대해서 배웠다.

 

React Routing - Rising Camp 12th WEB

SPA 방식의 어플리케이션에서 여러 페이지를 처리할 수 있도록 도와주는 react-router-dom 라이브러리를 활용해보며, 리액트 라우팅에 대해 이해해봅시다.

inbroz-charles.gitbook.io

개인적으로 리액트에서 가장 큰 장점이라 생각되는 부드러운 넘어감(?)을 구현해보는 시간이었다. 

 

1. header 완성화면 

페이지 각각은 아직 구현중이다. 

Kurly홈 이미지를 누르면 Main화면으로 넘어온다. 

 

 

다른 버튼들도 마찬가지로 누르면 각각 이동한다. 

 

2. 구현 

리액트의 react-route-dom을 활용했다.

지금까지 작성한 App.js 코드이다. 

 

App.js

import { BrowserRouter , Route, Routes} from "react-router-dom";
import Main from "./pages/Main";
import Header from "./components/Header";
import Best from "./pages/Best";
import Product from "./pages/Product";
import TimeSales from "./pages/TimeSales";
import Benefit from "./pages/Benefit";


function App() {
  return (
    <div className="root-wrap">
      <BrowserRouter>
      <Header />
        <Routes>
          {/* 주 페이지 */}
          <Route path="/" element={<Main/>} />
          <Route path="/collections/market-newproduct" element={<Product/>} />
          <Route path="/collections/market-best" element={<Best/>} />
          <Route path="/collections/market-time-sales" element={<TimeSales/>} />
          <Route path ="/market-benefit" element={<Benefit/>}/>
          {/*  */}
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;

<BrowserRouter>

- 라우팅에 포함되는 페이지들은 모두 이 컴포넌트에 의해 감싸진다.

-즉, 라우터 역할을 담당함 ! 

 

<Routes>

- 여러 Route를 감싸 그 중 경로가 일치하는 하나의 Route를 렌더링 시켜줌 ! 

 

<Route>

- path="경로 작성" element="띄워줄 컴포넌트 넣어줌"

- url뒤에 *가 들어간 경우 : 컴포넌트에 여러 경로를 매칭 할 때 ! 


componenets/Header.jsx

import React from 'react'
import { Link } from 'react-router-dom'

export default function Header() {
  return (
    <div className ="header-container">
        <div calssName="header-wrap">
            <div className="header-top-wrap">
                <Link style={{display:'flex',alignItems:'center'}} to="/">
                    <img
                    src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODIiIGhlaWdodD0iNDIiIHZpZXdCb3g9IjAgMCA4MiA0MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGZpbGwtcnVsZT0ibm9uemVybyIgZmlsbD0ibm9uZSI+CiAgICAgICAgPHBhdGggZD0iTTAgMGg4MnY0MkgweiIvPgogICAgICAgIDxwYXRoIGQ9Ik02Mi41Ljk2NWMxLjAyNi0uNTU3IDIuNDY2LS43MTggMy4zNTYuMTA3Ljg5LjgyNS42NzYgMi4wNDggMCAzLjk3MyAwIDAtMS41MDUgNC4wNjYtMy4wNTUgOC4yNjJsLS4zOTggMS4wOGMtMS40MTQgMy44My0yLjc2MiA3LjQ4Ny0yLjkyNyA3Ljk2My0xLjQ5OCA0LjI0NSAxLjk2NyA0LjEyMiA0LjAyNC0uMTUyIDEuMTU5LTIuMzk0IDIuNjQ0LTYuMzU3IDIuNjQ0LTYuMzU3LjUyNC0xLjU2My42ODItMi41MDQuMzU5LTIuODI4LS4xMDctLjExMy4wNDUtLjI1Mi4xOC0uMzIzIDIuMjY5LTEuMTQ5IDQuNjMtLjA3MiAzLjMzNiAzLjMxbC0uMDU0LjEzOGMtLjM4Ny45NzgtMi42OCA2LjczMy0yLjY4IDYuNzMzLS42NzYgMS42Ni0uNTk1IDMuMjM2LjQxOCAzLjIzNi42ODYtLjAwNCAxLjQ2LS4zODUgMi4zMDQtMS4wODggMS44MTgtMS41MDQgMy4yMjItNC4zMTIgMy43MjctNS40NTQuMjMtLjUwOCAxLjA4Ny0yLjQyIDEuNzY2LTQuMzYxLjIzNi0uNjY1LjM2OS0xLjM2LjM5NS0yLjA2NWEuNDQzLjQ0MyAwIDAgMSAuMTk0LS40NTkgMy41NzggMy41NzggMCAwIDEgMS42Ny0uNDIgMS44MDUgMS44MDUgMCAwIDEgMS40NjUuNzA1Yy40NDMuNTk4LjU2NiAxLjU3OS4xMDMgMi44MDgtLjEyLjMyLTMuNzc1IDkuOTU4LTMuNzc1IDkuOTU4di4wMjZjMi4wNDEtMS4yMjMgMy44Ny0xLjMxMyA0Ljk1My0uODU0bC0uMDAzLS4wMTNjMS40OTUuNjQ3IDEuOTkgMi40NC45MzggMy41NTktLjEwMy4xMS0uMzYyLjA4NC0uMzYyLS4wOS0uMDk0LTEuMjUzLTIuNTE3LTMuNDk1LTYuMTA5LTEuMDc1bC0uMTQ1LjM4NS0xLjA2OCAyLjgwOGMtMi42MiA3LjAxOC01LjQwMyAxMi4xMzYtOS40MTUgMTEtMi42ODgtLjc2LTIuMzc3LTQuNjA3LjUxNS03Ljc5YTU0LjkgNTQuOSAwIDAgMSA2LjQ5LTUuODk4Yy4wNjgtLjE4OC4xMy0uMzUuMTg4LS41MTEuMjc4LS43OC40OTEtMS40MzQuNzkyLTIuMjY1bC4xNTktLjUxOGMtLjE3OC4yLS40OTguNTczLS43MTIuODEyLS43MTIuOC0yLjQ5NCAyLjc1Ny01LjMyOSAyLjIwN2wtLjIzNC0uMDUyYy0yLjA1LS41MDgtMi42MDgtMS45ODYtMi42NTUtMy4yNzctMi4xNDIgMi42NTYtNC4zNTEgMy40MjYtNS44MDcgMy4zOS0xLjk0OC0uMDQ4LTMuMzc4LTEuNTE0LTIuNDI3LTQuMjkgMS4wNTgtMy4xMDYgNS41LTE1LjMzMiA2Ljc5NS0xOSAuNDg1LTEuNTguNjY2LTIuNTguMTg0LTIuOTc0LS4xMjMtLjEwMy4wNTItLjI2NS4yLS4zNDZ6bTguMzY0IDI4Ljc3OGMtMS4xMDMuODgtNS41MjYgNC41My02Ljc1MiA3LjQ0MS0uNTA1IDEuMTk3LS4zNzYgMi4xNDkuNDg4IDIuMjMzIDEuOTYuMTk0IDQuMDEyLTMuODE4IDYuMjI4LTkuNTEyek0xNi4wMjggNS4zNTJjLS4wODcuMzMyLTEuMzE5IDMuODYtMi43MDEgNy43NDlsLS4yMDkuNTg2LS4yMS41ODktLjIxNS42MDRjNC42OTEtMS4xMjMgMTMuMDY0LTYuNTcgMTQuMDM1LTEwLjA4NS4xMi0uMTYxLjI5LS4yMi41NjYtLjAzNS40OTUuMzMuNjg2IDEuMTU1LjQ5NSAxLjkxOC0uNzY0IDMuMDM4LTYuNDE2IDcuMzQxLTExLjM3OSA5LjU1NC42MTIgMS42MzcgMi42ODIgNi4yNjcgNC4yMDYgOS4xMTEgMS42NjMgMy4xMTkgMy40MiA0LjU3NSA2LjE0NyA0LjczNyAxLjQ2LjA4NSAzLjAxNC0uNDQ3IDMuODkzLTEuMjJsLjE0OC0uMTQtLjAxMy4wM2MuMTk0LS4yMDQuNTExLjA3Ny4zNjYuMzIzYTYuNSA2LjUgMCAwIDEtNC45OTIgMi44NjdjLTYuMzQ1LjQyNy04Ljc3NC0zLjg3LTEzLjMwNC0xNC40OTQtLjM2Ni4xMjYtLjgwOS4yODgtMS4yNTUuNDUtLjA3NS4xODctMi4wNyA1LjY0Mi0yLjEzIDUuODIzLS45NDQgMi44Ny0xLjAwNSA0LjQ0Mi0uMzU4IDQuODk1LjE0NS4wOS4wNzQuMzMzLS4xNzguNDE0LTIuNTI3Ljc5Ni00Ljg1My0uNjk2LTMuNTU5LTQuNDQyIDEuMTYxLTMuMzE2IDUuNjktMTYuMTggNi45MTQtMTkuNjI2LjQyNy0xLjI5NC4xOTctMi4xMjUtLjQ5Mi0yLjMwNkM4LjUwNiAxLjc4Ljg3NyA4Ljc0OSAxLjk3MSAxNS4xODRjLjE5IDEuMTIuOTggMS43NDcgMS4zNzggMS42NjNhLjEzMy4xMzMgMCAwIDEgLjE1Ni4xNTkgMS41MDggMS41MDggMCAwIDEtMS44NDUgMS4wMzJDLjQ5IDE3Ljc4Mi4xMDcgMTYuNTI3LjA0MyAxNS44OC0uNjAxIDkuMjIgNi4xNDggMS4yMyAxMi4zODkuNThjMi4zNzgtLjI1IDQuNjEuOTYgMy42NCA0Ljc3MnptMjQuMDQgOS45MTMtLjA2LjIwNy0yLjgzIDguMTZjLS4zMDQuODUtLjEgMS43MzcuNTAxIDEuOTAyIDEuNzU3LjQ4MiA0LjAyOC0yLjE0NSA1LjEzMS00LjczM2E2Ny43OTQgNjcuNzk0IDAgMCAwIDEuNDc2LTMuODE1Yy41ODItMS42NDMgMS4xMDYtMy4xODMuNzgzLTMuOTA4LS4wNzUtLjE2OC4wNDUtLjI1Ni4yMjMtLjM1LjUwNS0uMjU1IDIuMjI2LS44MjUgMy4xNDEuMDY4LjY5NS42NzQuNjA5IDEuNzcxLS4wMyAzLjQzN2wtLjA5Ni4yNDIuMjItLjI3M2MyLjcwMy0zLjMgNC43OTItNC4yOTIgNi41NjMtMy41OTdsLjE0Ny4wNjJjMi4zODEgMS4wNzQgMS4xNDYgNS4yMTUtMi4xMTYgNS40OC0uMi4wMTctLjM1Ni0uMTI2LS4xNTgtLjQwNy4zOTUtLjYwNS4zNTYtMS45MDktLjc5Ni0yLjAyMi0xLjE1Mi0uMTEzLTIuODMgMS4yMDctNC4wMzggMi44NDQtMS4wODQgMS40NS0yLjIgMy45MTEtMy4zMjIgNy4yNzMtLjI3Mi44MTgtLjE0MyAxLjAxMi0uMTEgMS4wNjdhLjEuMSAwIDAgMSAwIC4wOTRjLS4xNDMuMjcyLS45NjUuNTk2LTEuNzYuNTk2LTEuNjI1LS4wMDctMi4yOTEtLjk0NS0xLjk2Ny0yLjQzNy0xLjg0OCAxLjc2NC0zLjcxMSAyLjYxNC01LjM1NSAyLjQ2NmEyLjUyNCAyLjUyNCAwIDAgMS0yLjIzNi0zLjEwM2MtMS40MjYgMS44MDktMy41NDIgMy4yNjgtNS42OTcgMy4wNjctMi4xNTUtLjItMy41LTEuNjY2LTIuODAyLTQuNzg4LjU5LTIuNTk4IDEuNTkyLTUuMjkgMi4yMDctNy4wMjcuNTE0LTEuNDU2LjYxOC0yLjQwNy4yOTQtMi43NS0uMTAzLS4xMTQuMDU1LS4yNS4xOTQtLjMyNCAxLjY5LS44ODYgNC4zOTQtLjMxNCAzLjYzIDIuMDktLjgwMiAyLjUyNy0yLjI1NSA2LjQ5LTIuNTUgNy40LS43MzcgMi4yODctLjI5IDMuNTIzLjc1NSAzLjU4IDEuMDQ1LjA2IDIuNDMtLjk2IDMuNDItMi41MDMgMS43Ni0yLjUyNCAyLjU4MS01LjY4NSAzLjM3Ny03Ljg4Mi4yMDQtLjU2LjUyNy0xLjg2Ni4xODUtMi4zNTItLjA5MS0uMTIzLjA2Ny0uMjU4LjI3NS0uMzcyIDEuNTM3LS44NDkgNC4yODUtLjY0IDMuNDAyIDIuNjA4eiIgZmlsbD0iIzVGMDA4MCIvPgogICAgPC9nPgo8L3N2Zz4K"
                    alt="로고"
                    />
                    
                </Link>
                <div className="search-wrap">
                <input type ="text" classNaem="search-text"/>
                <button class="search-button">
                    <img src="data:image/png;base64,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"
                    style={{width:'30spx',height:"30px"}}/>


                </button>

                </div>
            </div>
            <div className="header-bottom-wrap">
                <ul>
                    <li>
                        <Link className="header-nav-item" to='/collections/market-newproduct'>
                            신상품
                        </Link>
                    </li>
                    <li>
                        <Link className='header-nav-item' to="/collections/market-best">
                            베스트
                        </Link>
                    </li>
                    <li>
                        <Link className="header-nav-item" to ='/collections/market-time-sales'>
                            알뜰쇼핑
                        </Link>
                    </li>
                    <li>
                        <Link className="header-nav-item" to="/market-benefit" >
                            특가/혜택
                        </Link>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    
  )
}

거의 HTML.. 

 

여기서 <Link>가 눈에 띌 것이다. 

Link는 클릭 시 바로 이동하는 로직 구현에 최적화 된 태그이다. 

이 태그 말고 비슷하게 작동할 수 있는 방법은 Navigate Hook 사용하기!

 

react를 배우기 전에는 <a>태그를 사용하여 링크로 이동하였다. 

 

그런데 <Link>와는 기능이 거의 비슷한데 ! 왜 <Link>가 나오게 되었을까?

 

에어비엔비, 마켓컬리, 넷플릭스와 같은 리액트 프레임워크를 사용하는 웹과 리액트 프레임워크를 사용하지 않는 웹을 비교해보면 된다 

바로 페이지 이동 시 발생하는 새로고침의 유무 이다.

 

<Link>는 브라우저 주소만 변경할 뿐, 페이지를 새로고침하지 않고 

<a>태그는 브라우저의 주소를 변경하면서 페이지를 새로고침한다! 

이 두 링크만을 비교해봐도 리액트 프레임워클르 사용하는 웹이 훨씬 부드럽게 작동한다는 것을 알 수 있다. 

(경혜여고 미안해요 .. ) 


@import 'reset.css';

/* 헤더 CSS */
.header-container{
/* 
  flex-direction: column; */

  display:flex;

  max-width:1440px;
  padding: 40px 100px 20px;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0px 0.5px 3px 0.6px gray inset;
  
}

.header-top-wrap{

  flex-direction: row;
  display:flex;
  padding: 12px 0;
  width:100%;
  max-width: 1300px;
  margin-left:50px;
  margin-bottom:10px;
}

.search-wrap{
  border: solid #6c00c5;  
  
  display: flex;
  width:300px;
  margin-top:5px;
  margin-left:200px;
  height:40px;

  border-radius: 10px;
}
  
.search-wrap input {

  border:none;
  width:260px;
  font-weight: 600px;
  font-size: large;
  border-radius: 10px;
  
}

.search-wrap button{
  background-color: white;
  border-radius: 10px;
  border:none;
  cursor:pointer
  
}

.header-bottom-wrap{

  width:100%;
  max-width: 1300px;
  margin-left:100px;
  
}

.header-bottom-wrap ul{
  display: flex;
  margin-left : 70px;
}

.header-nav-item{
  text-decoration: none;
  padding: 10px 20px ;
  margin-left: 50px;

  font-size: 15px;
  font-weight: 600;
  font-style: black;
  cursor: pointer;
  
}

.header-container li:hover,
.header-container li:active{
  text-decoration: underline;
}

 

 

아직 많이 부족하지만 한 페이지씩 짜 볼 예정이다 ~ !