본문 바로가기
(심층)리액트

다시 시작하는 리액트 - 리액트 실무 기초 3 Quiz

by min' 2023. 3. 30.
728x90
반응형

 

- Quiz_버킷리스트 상세 페이지 만들고 이동시키기

 

 버킷리스트 상세페이지를 만들고 리스트 항목을 누르면 이동시키자!

💡 버킷리스트 항목이 나오는 부분만 route로 이동시켜주세요 🙂

 

- 예시 답안(메인페이지 / 상세페이지)

 

 

- 내가 만든 버킷리스트 퀴즈(메인페이지 / 상세페이지)

 

 

bucket 리스트 항목이 나오는 부분만 라우터로 이동시키라고 했으니

내가 만들어둔 component BucketList를 Router 안으로 넣어줄 것이다.

 

1. 그러기 위해서 src 폴더 안에 share 폴더를 만든 후 그 안에 Router component를 만들어준다.

 

2. 그리고 Router component가 라우터 기능을 할 수 있도록 react-router-dom을 설치해준다.

 

react-router-dom 설치 명령어 - yarn add react-router-dom@6.9

현재 나는 npm이 아닌 yarn을 사용하여 공부를 진행하고 있기 때문에 설치 역시 yarn으로 진행한다.

그리고 react-router-dom의 최신 버전은 6.9이다. 라이브러리 설치시 버전을 명시해주는 것이 좋다.

 

3. src 폴더 안에 page 폴더를 하나를 더 만들어 안에 Detail component를 추가해준다.

 

- Detail.js

import React from "react";
import styled from "styled-components";

const SubTitle = styled.h2`  color: rgba(0, 0, 0, 0.8); 
font-size: 1.8rem;`;

export default function Detail() { 
  return <SubTitle>상세페이지 입니다!</SubTitle>;
}

 

4. react-router-dom을 설치하고 난 후에는 Router component 안에 Routes, Route를 import 해준다.

버전이 6으로 업그레이드가 되고 난 후에는 router를 이렇게 작성한다.

Route를 Routes로 감싸주고 가장 최상단을 BrowserRouter로 감싸준다.나는 여러 component에서 router의 기능을 사용할 수 있도록 하기 위해서index.js에서 최상위 component인 App을 BrowserRouter로 감싸줬다.(물론 import는 필수)

 

Route에는 path와 element를 넣어준다.

path에는 이동할 주소를 담아주고 element에는 component를 넣어

지정된 path로 이동시 해당 component가 렌더링되도록 한다.

 

- index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render( 
  <BrowserRouter>   
    <App /> 
  </BrowserRouter>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
- Router.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import BucketList from "../BucketList";
import Detail from "../page/Detail";

export default function Router({ list }) { 
  return (   
    <>     
      <Routes>       
        <Route path="/" element={<BucketList list={list} />} />       
        <Route path="/detail" element={<Detail />} />     
      </Routes>   
    </> 
  );
}

 

5. 만들어진 Router 안에 BucketList, Detail component를 추가해준다.

패이지에 들어갔을 때 가장 먼저 뜨는(고정된) 페이지는 path="/"로 지정해준다.

그리고 우리는 BucketList component가 화면에 가장 먼저 뜨도록 하기 위해서 element로 BucketList를 넣어준다.

그리고 App component에 state로 담겨 있는 list 배열을 props로 전달해준다.

(BucketList component에서 사용해야 하기 때문)

 

하지만, Router 내부에 BucketList component가 담겨 있는데 Router에는 list 배열이 현재 없다.

그렇다면 어떻게 해야 할까?

당연히, App component에 Router가 있으므로 Router 역시 props로 list 배열을 받아야 한다.

 

- App.js

<Router list={this.state.list} />
- Router.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import BucketList from "../BucketList";
import Detail from "../page/Detail";

export default function Router({ list }) {
  return (
    <>
      <Routes>
        <Route path="/" element={<BucketList list={list} />} />
        <Route path="/detail" element={<Detail />} />
      </Routes>
    </>
  );
}

 

6. 순서가 조금 틀린 것 같지만,

App component에 BucketList component가 들어가 있던 자리를 Router component로 대체해주고

import해주면 끝난다! 

 

스타일은 styled-components를 계속해서 사용해서 만들었다.

 

+

 

router의 기능에 관하여 좀 더 자세하게 알아보자는 차원에서

match되는 path가 없을 경우 NotFound component로 이동하도록 해준 다음,

이전 page로 이동할 수 있게 하는 버튼도 하나 추가하였다.

 

1. page 폴더 내에 NotFount component 생성.

component 내에 글 추가해주기. 난 해당하는 페이지가 없다는 뜻에서 404 Error를 띄웠다.

이렇게 NotFound component를 생성해주었다면 Router component로 이동하여 Route를 하나 더 만들어준다.

path = "*" element={<NotFound />} /> 이렇게 추가를 해준다.

 

- *는 무엇인가?

 

URL 변경이 감지되면 첫 번째 Route부터 순차적으로 탐색을 하게 되는데,

위의 내용과 모두 match가 되지 않을 때 *에 해당하는 component를 렌더링하게 된다.

즉, *는 위의 조건들 이외의 라는 의미를 지닌다.

 

고로 해당하는 path가 없을 때 NotFound component가 뜨게 될 거임.

 

- NotFound.js

import React from "react";
import styled from "styled-components";
import { useNavigate } from "react-router-dom";

const NotFoundWrap = styled.div`
  width: 100%;
  height: 360px;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
`;

const NotRight = styled.h1`
  color: rgba(0, 0, 0, 0.8);
  font-size: 1.4rem;
`;

const GoBack = styled.button`
  padding: 10px 20px;
  background-color: transparent;
  border: 1px solid rgb(81, 93, 196);
  border-radius: 50px;

  color: #3e3885;
  font-weight: 600;

  cursor: pointer;

  &:hover {
    background-color: #3e3885;

    color: white;
  }
`;

export default function NotFound() {
  const navigate = useNavigate();

  return (
    <NotFoundWrap>
      <NotRight>404 Error</NotRight>

      <GoBack
        onClick={() => {
          navigate(-1);
        }}
      >
        {`<< Go Back`}
      </GoBack>
    </NotFoundWrap>
  );
}
- Router.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import BucketList from "../BucketList";
import Detail from "../page/Detail";
import NotFound from "../page/NotFound";

export default function Router({ list }) {
  return (
    <>
      <Routes>
        <Route path="/" element={<BucketList list={list} />} />
        <Route path="/detail" element={<Detail />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </>
  );
}

 

2. 이제 NotFound component에 버튼을 하나 만들어준다.

난 현재 styled-component를 사용하고 있으니 버튼의 이름을 GoBack이라고 지정해주겠다.

(스타일은 위 코드에 있으니 생략)

 

여기서는 react-router-dom 안에 있는 기능인 react hook useNavigate()를 사용할 것.

사용하기 쉽도록 변수 navigate에 useNavigate()를 담아주고

GoBack 버튼을 클릭했을 때 navigate가 실행되도록 한다.

 

<GoBack onClick={ ( ) => { navigate(-1)} }> {`<< Go Back`} </GoBack>

 

앞으로 가기 :  onClick={ ( ) => navigate(-1) }
뒤로 가기 : onClick={ ( ) => navigate(1) }

 

이렇게 구현이 가능하다.

 

- NotFound.js

import React from "react";
import styled from "styled-components";
import { useNavigate } from "react-router-dom";

const NotFoundWrap = styled.div` 
  width: 100%; 
  height: 360px; 

  display: flex; 
  flex-direction: column; 
  align-items: center; 
  justify-content: space-between;
`;

const NotRight = styled.h1` 
  color: rgba(0, 0, 0, 0.8); 
  font-size: 1.4rem;
`;

const GoBack = styled.button` 
  padding: 10px 20px; 
  background-color: transparent; 
  border: 1px solid rgb(81, 93, 196); 
  border-radius: 50px; 
 
  color: #3e3885; 
  font-weight: 600; 

  cursor: pointer; 

  &:hover {   
    background-color: #3e3885;   
    color: white; 
  }`;

export default function NotFound() { 
  const navigate = useNavigate(); 

  return (   
    <NotFoundWrap>     
      <NotRight>404 Error</NotRight>     

      <GoBack
        onClick={() => {         
          navigate(-1);       
        }}     
      >       
        {`<< Go Back`}     
      </GoBack>   

    </NotFoundWrap> 
  );
}

 

- 완성작

 

이렇게 지정되지 않은 path로 이동할 경우 404 Error가 뜨는 NotFound component로 이동함.

 

728x90
반응형

댓글