[TIL # 60] React Basic (5)

Yejin Yang·2022년 8월 5일
0

[TIL]

목록 보기
59/67
post-thumbnail

[수업 목표]

  1. React Router 에 대해서 이해한다.
  2. 페이지 간 이동 및 파라미터 전달에 대해서 이해한다.
  3. 하단 탭을 통한 페이지 이동을 구현해본다.

⭐️ 새롭게 안 사실

$ yarn add react-router-dom@6
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);
  • index.js 에서 App 을 BrowserRouter 로 감싸야한다. 이렇게 해야만 해당 App 에서 브라우저 라우팅 기능을 사용할 수 있다.

폴더 구조 관련 :
routes 폴더를 만들고 그 안에다가 컴포넌트 파일을 넣어주기도 하는데 정답이 정해져있는 것이 아니므로, 프로젝트 등을 진행하실 때에는 팀 내에서 폴더 구조를 협의하고 시작하는 것을 추천!

// App.js
import { Link, Route, Routes } from 'react-router-dom';
  • Routes 는 포함하는 주소 변경을 감지하고 일치하는 Route 를 찾아서 표시해주는 역할
<Route path="posts" element={<Posts/>}/>
  • 컴포넌트 연결: 현주소/posts 로 접근했을 때, Posts 컴포넌트가 보이도록 설정
<Link to="posts">Posts</Link>
  • 해당 페이지로 접근할 때는, a 태그가 아니라 Link태그 사용한다.

Nested Route

<Route path="posts" element={<Posts/>}>
  <Route path=":postId" element={<PostDetail/>}/>
</Route>
  • Posts 페이지에서는 글 제목만 보여주고, 제목을 누르면 PostDetail 페이지가 보이는 형태

  • 이러한 형태를 Nested Route 라고 한다. 서브 라우트라고도 표현하는데, 이렇게 작성하게 되면 URL 구조가 주소/posts/:postId 와 같이 계층적으로 이어지면서 설정된다.

  • 뿐만 아니라 Nested Route 를 쓰면 Outlet 이라는 것을 통해서, 부모 Route 의 요소를 표시하면서 동시에 하위 Route 요소를 표시하게 된다.

  • :postId 처럼 문자 앞에 : 를 써주게 되면, 그때부터는 단어 그 자체가 아니라 변수로서 인식하겠다는 뜻이 됩니다. 그래서 이렇게 작성하면 posts/1 이라는 주소로 사용자가 접근할 경우, :postId 에 연결된 컴포넌트가 보여지게 되고, 해당 컴포넌트에서는 주소에 명시된 1이라는 숫자를 postId 라는 이름의 변수로 사용할 수 있게 된다. 변수를 가져오는 것은 useParams 라는 Hook 이 담당하게 된다.

Outlet

import { Outlet } from 'react-router-dom'

하위 컴포넌트 주소로 이동 시 하위 컴포넌트 내용을 보고 싶다면 <Outlet/> 이라는 태그를 추가해야 한다.

Index Route

Index Route 는 Nested Route 구조에서, / 뒤에 아무도 없는 주소 상태일 때 보여줄 컴포넌트를 정하는 Route 를 말한다.

<Route path="posts" element={<Posts/>}>
  <Route index element={<PostIndex/>}/>
  <Route path=":postId" element={<PostDetail/>}/>
</Route>

이렇게 작성하면, /posts 로 접근했을 때, PostIndex 컴포넌트 내용이 보인다!

useParams

useParams는 URL 인자들의 key/value(키/값) 짝들의 객체를 반환한다. 현재 <Route> 의 match.params에 접근하기 위해 사용한다.

예시)

// App.js
<Route path=":postId" element={<PostDetail/>}/>

-> postId 라는 이름으로 값을 넘기도록 설정했다.

const params = useParams();
console.log(params) // {postId:~}

그렇기 때문에 params 안에는 postId 라는 키로 값이 담겨 있다.

import React from 'react'
import { useParams } from 'react-router-dom';
import {postData} from '../../../constants/postData'

function PostDetail() {
  const params = useParams();
  const post = postData.find((post) => post.id === parseInt(params.postId))

  return (
    <div>
      {post.title}
      {post.body}
    </div>
  )
}

export default PostDetail

📌 꼭 기억할 것

위 내용 전부

{posts.map((post) => {
  return (
    <p key={post.id}>
      <Link to={`/posts/${post.id}`} state={{ post:posts.find((data) => data.id === post.id) }}>{post.title}</Link>
    </p>
  )
})}

postData 를 또 불러오는게 비효율적이라고 판단, Link 를 타고 이동하면서 데이터를 넘겨주기! Link 태그에 state 명시!

import React from 'react'
import { useLocation, useParams } from 'react-router-dom';

function PostDetail() {
  const params = useParams();
  const location = useLocation();
  const {post} = location.state

  return (
    <div>
        {post.title}
        {post.body}
    </div>
  )
}

export default PostDetail

이렇게 받아서 사용하기!

useNavigate

주소 이동을 위한 Hook, Link 와는 다르게 함수 안에서 주소 이동 동작을 실행하고자 할 때 사용한다.

import { useNavigate } from "react-router-dom"

const navigate = useNavigate()
navigate("주소",  옵션)

옵션

// 옵션 1
// 이동하면서 접근 이력을 유지할 지, 버릴 지 선택합니다.
{ replace: true }

// 옵션 2
// 주소 이동하면서 전달하고자 하는 값을 명시합니다.
{ state: 넘어가면서 전달하고자 하는 데이터 }]

뒤로가기 / 앞으로가기

navigate(숫자)
import React from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom';

function PostDetail() {
  const params = useParams();
  const location = useLocation();
  const navigate = useNavigate();
  const {post} = location.state ? location.state : {post:''}

  if (!post) return <p>Not Found</p>
  return (
    <div>
        {post.title}
        {post.body}
        <button onClick={() => navigate(-2)}>뒤로 2번가기</button>
        <button onClick={() => navigate(-1)}>뒤로 1번가기</button>
        <button onClick={() => navigate(1)}>앞으로 1번가기</button>
        <button onClick={() => navigate(2)}>앞으로 2번가기</button>
    </div>
  )
}

export default PostDetail
profile
Frontend developer

0개의 댓글