토이프로젝트 post page 구현기(1): react router

coolchaem·2021년 12월 21일
1

toyproject

목록 보기
6/21

Post Page 구현기(1)

Post page을 구현하는 과정을 적었다.

1. react route에 page 추가

page를 구현하기 전 route에 먼저 연결하였다.

  • 빈 page를 넣은 이유?
    코드를 다 넣은 후 route에 추가하면 API 에러랑 섞여 구분할 수 없고 routing parameter도 필요하기 때문에 먼저 연결하였다.
// post page
import React from 'react';
import PostViewer from '../../components/organisms/post/PostViewer';

const PostPage = () => {
  return <PostViewer />;
};

export default PostPage;

// post viewer component
import React from 'react';

const PostViewer = () => {
  return <div>글 보기 페이지 입니다.</div>;
};

export default PostViewer;
  • post는 특정 user 아래 있어서 nested router를 사용하였다. 해당 기능은 react-router v6부터 사용가능하다고 한다.
    • v5를 기준으로 작성하였으나 nested router기능이 더 깔끔해보이고 내부적으로 v6 패키지가 일부 깔려있어 정식으로 migration 과정을 거쳤다.
    • 먼저 설치!
npm install react-router@6 react-router-dom@6
  • 그리고 url 형태가 'userId/postUrlTitle'로 되어있는데 userId에 여러 page에 대해 route 정보가 있는데 마이그레이션하면서 route path를 userId/*로 바꾸면서 동일하게 VelogPage로 전환된다.
const App = () => {
  const userId = useAppSelector(state => state.userState.id);
  return (
    <>
      <BrowserRouter>
        <ul>
// ...
        </ul>
        <Routes>
          <Route index element={<HomePage />} />
          <Route path="@:userId/*" element={<VelogPage />} />
// ...
        </Routes>
      </BrowserRouter>
    </>
  );
};

export default App;
  • 그리고 velog page에 post url을 처리할 수 있게 PostPage route를 추가하였다.
import React from 'react';
import { Link, Route, Routes } from 'react-router-dom';
import UserPage from './UserPage';
import ArticlePage from './ArticlePage';
import SeriesPage from './SeriesPage';
import PostPage from '../home/PostPage';

const VelogPage = () => {
// ...
  return (
    <div>
// ...
      <Routes>
        <Route path="/" element={<ArticlePage />} />
        <Route path=":urlSlug" element={<PostPage />} />
        <Route path="series" element={<SeriesPage />} />
        <Route path="about" element={<UserPage />} />
      </Routes>
    </div>
  );
};

export default VelogPage;

2. Post Viewer 구현

React Route params 호출

post url 정보를 다시 가져오기 위해서 hook을 사용하여 params를 호출해보았다.

  • useParams
    • URL parameter로 준 내용을 key/values 형태의 object로 반환해준다. Route의 match 정보의 property인데 parameter만 쓴다면 사용하는 것이 좋아보였다.
    • 참고: redux로 store에 post card 생성 시 경로를 저장하는 방법도 생각했었지만, 메모리 공간을 많이 차지하고 서비스 사용자 모두로부터 자주 추가되고 삭제될 수 있는 가능성을 가진 내용을 store로 저장하기엔 트래픽 부담이 있었다.
import React from 'react';
import { useParams } from 'react-router-dom';

const PostViewer = () => {
  let { userId, urlSlug } = useParams<{userId: string, urlSlug: string}>();

  return <div>글 보기 페이지 입니다.</div>;
};

export default PostViewer;

GET API 호출

사용하는 axios로 url get을 해온다.

import axios from 'axios';
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { API_HOST } from '../../../constant';

const PostViewer = () => {
  const [postBody, setPostBody] = useState<HTMLHtmlElement>();
  let { userId, urlSlug } = useParams<{userId: string, urlSlug: string}>();

  useEffect(() => {
    axios({ baseURL: API_HOST, url: `/@${userId}/${urlSlug}` })
      .then(response => {
        console.log(response.data);
        setPostBody(response.data);
      }).catch(error => {
        console.error(error);
      });
  }, [userId, urlSlug]);

  console.log(postBody);

  return (
    <div>
      글 보기 페이지 입니다.
    </div>
  );
};

export default PostViewer;

3. Not found page 적용

404 에러 핸들링을 위해 Not found page를 만들어서 App.tsx route path 마지막 줄에 적용해보았다.

<Route path='*' exact={true} component={NotFoundPage} />

baseUrl/ 뒤에 route path가 없는 url을 쳤을 때 NotFoundPage가 호출되었다.

기타 문제

blog url로 바로 접근했을 대에도 not found page를 적용하고 싶었는데 프로젝트 webpack 설정의 오류인지 baseUrl/page1/page2로 접근이 되지않았다.
index.js를 가져오지 못 해서 다음 시간에 추가로 적용하고 viewer에 post내용까지 보여주는 것을 구현할 것이다.


React Router

이번 구현을 하면서 조사한 내용은 react route는 router 종류가 2개이다.

Browser Router

  • HTML5 history API로 구현된 Router이다.
    • history 객체를 통해 브라우저의 세션 기록에 접근할 수 있는 방법을 제공한다고 한다.
    • 일반적으로, 페이지 뒤로 가기와 앞으로 가기가 대표적이다.
window.history.back()
window.history.forward()
  • 일반적으로 사용하는 Router이다.
<BrowserRouter basename="/calendar">
    <Link to="/today"/> // renders <a href="/calendar/today">
    <Link to="/tomorrow"/> // renders <a href="/calendar/tomorrow">
</BrowserRouter>

Hash Router

  • url에 #과 같은 hash를 붙여넣는다.
<HashRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="#/calendar/today">
  • 그래서 서버에 url을 보낼 수 없다!
  • 정적인 페이지를 호출할 때 사용할 수 있다고 한다.

https://v5.reactrouter.com/web/api/BrowserRouter
https://developer.mozilla.org/ko/docs/Web/API/History_API

profile
Front-end developer

0개의 댓글