목표

  • 상세 페이지 만들기
  • axios로 상세 페이지 서버 데이터 받기

 


결과 화면

 


1. App.tsx path 설정하기

  • src/App.tsx

상세페이지의 url이 '/board/숫자' 형식이 될 수 있도록 라우터의 path를 :id로 설정한다.

import React from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import './assets/scss/common.scss'

import BoardList from './pages/board/list'
import BoardDetail from './pages/board/detail'
import BoardCreate from './pages/board/create'
import BoardModify from './pages/board/modify'

const App = () => {
  return (
    <>
      {
        <BrowserRouter>
          <Routes>
            <Route>
              <Route path="/board" element={<BoardList/>}/>
              <Route path="/board/:id" element={<BoardDetail/>}/>
              <Route path="/board/create" element={<BoardCreate/>}/>
              <Route path="/board/modify/:id" element={<BoardModify/>}/>
            </Route>
          </Routes>
        </BrowserRouter>
      }
    </>
  )
}

export default App

 

 

2. 목록 페이지에서 상세 페이지로 이동하기

  • src/pages/board/list/index.tsx

Link 컴포넌트의 경로를 데이터베이스의 id 값으로 설정한다.

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

const BoardList = () => {
  return (
    <div className="board-list">
      <table>
       ...
        <tbody>
          {
            currentPost.map((board, index: number) => {
              return (
                <tr key={index}>
                  <td>{index + 1}</td>
                  <td className="title">
                    // 상세페이지로 이동
                    <Link to={`/board/${board.id}`}>{board.title}</Link>
                  </td>
                  <td>{dayjs(board.created_at).format('YYYY.MM.DD')}</td>
                </tr>
              )
            })
          }
        </tbody>
      </table>
    </div>
  )
}

export default BoardList

 

3. axios.get()으로 서버 데이터 받기

https://jae-study.tistory.com/80

Nest.js와 Psql을 사용해서 백앤드와 데이터베이스를 만들었다.

 

직접 백앤드와 데이터베이스를 만들어도 되고,

JSONPlaceholder 사이트를 통해 가짜 데이터를 받아와도 된다.

 

Postman을 통해서 GET으로 받아온 데이터를 확인할 수 있다.

 

 

  • src/pages/board/detail/index.tsx
  1. useEffect()를 안에 axios를 작성한다.
  2. 상세 페이지는 서버에서 데이터를 받아 화면에 보여주면 되기 때문에 get() 메서드를 사용한다.
  3. useParams() 훅을 사용해서 url의 파라미터 값에 해당하는 서버 데이터를 가지고 온다. 
  4. [setDetailBoardData] state 변수에 axios로 받아온 데이터를 저장한다.
import { useParams } from 'react-router'

const BoardDetail = () => {
  // hook
  const params = useParams().id

  // state
  const [detailBoardData, setDetailBoardData] = useState<any>([])

  useEffect(() => {
    axios.get(`http://localhost:3001/board/${params}`)
      .then((response) => {
        setDetailBoardData(response.data)
      })

      .catch(function(error) {
        console.log( error)
      })
  }, [])

  return (
    <div className="board-detail">
	  ...
    </div>
  )
}

export default BoardDetail

 

4. 서버 데이터를 화면에 출력하기

[setDetailBoardData] state 변수에 저장한 데이터를 화면에 출력한다.

const BoardDetail = () => {
  // state
  const [detailBoardData, setDetailBoardData] = useState<any>([])

  useEffect(() => {
    ...
  }, [])

  return (
    <div className="board-detail">
      <Title children={detailBoardData.title}/>

      <div className="board-wrapper">
        <div className="board-header">
          <p>No.{detailBoardData.id}</p>
          <p>{dayjs(detailBoardData.created_at).format('YYYY.MM.DD')}</p>
        </div>

        <div className="board-content">
          <p>{detailBoardData.content}</p>
        </div>
      </div>

      <div className="grid-2">
        <Link to={`/board/modify/${detailBoardData.id}`}>
          <Button children="Modify" variant="primary"/>
        </Link>
        <Link to="/board">
          <Button children="List" variant="secondary"/>
        </Link>
      </div>
    </div>
  )
}

export default BoardDetail

 


전체 코드

  • src/pages/board/detail/index.tsx

FIXME:: state에 데이터를 저장할 때 타입을 any로 설정했다. 수정할 예정이기 때문에 타입에 주의한다.

import { useState, useEffect } from 'react'
import { useParams } from 'react-router'
import { Link, useNavigate } from 'react-router-dom'
import axios from 'axios'
import dayjs from 'dayjs'
import Button from '../../../components/form/Button'
import Title from '../../../components/text/Title'
import './index.scss'

const BoardDetail = () => {
  // hook
  const params = useParams().id
  const navigate = useNavigate()

  // state
  const [detailBoardData, setDetailBoardData] = useState<any>([])

  useEffect(() => {
    axios.get(`http://localhost:3001/board/${params}`)
      .then((response) => {
        setDetailBoardData(response.data)
      })

      .catch(function(error) {
        console.log( error)
      })
  }, [])

  return (
    <div className="board-detail">
      <Title children={detailBoardData.title}/>

      <div className="board-wrapper">
        <div className="board-header">
          <p>No.{detailBoardData.id}</p>
          <p>{dayjs(detailBoardData.created_at).format('YYYY.MM.DD')}</p>
        </div>

        <div className="board-content">
          <p>{detailBoardData.content}</p>
        </div>
      </div>

      <div className="grid-2">
        <Link to={`/board/modify/${detailBoardData.id}`}>
          <Button children="Modify" variant="primary"/>
        </Link>
        <Link to="/board">
          <Button children="List" variant="secondary"/>
        </Link>
      </div>
    </div>
  )
}

export default BoardDetail

 

#3
axios.get()과 useParams()을 통해
id별로 각각의 상세 페이지를 보여줄 수 있도록 만들었다.

+ Recent posts