목표

  • 수정 페이지 만들기
  • 게시글 삭제 버튼 만들기
  • axios.patch()로 서버 데이터 수정하기
  • axios.delete()로 서버 데이터 삭제하기

 


결과 화면

 


1. state 변수 만들기

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

    1. title(타이틀)과 content(콘텐츠) state 변수를 만들고,

    Input, Textarea 컴포넌트의 onChange 속성에 state 변수를 넣어 입력할 때마다 변하는 입력값을 state 변수에 저장한다.

 

    2. axios.get()으로 서버 데이터를 받아오고,

    수정 페이지는 기존에 등록했던 title과 content의 값을 수정해야 하기 때문에 [modifyBoardData] state 변수를 만들어 초기값을 설정한다.

 

    3. 페이지가 로딩되자마자 데이터들이 보여야 하기 때문에 useEffect()로 [modifyBoardData] state 변수에 초기값을 설정한다.

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

  // state
  let [modifyBoardData, setModifyBoardData] = useState<any>([])
  let [title, setTitle] = useState<string>(modifyBoardData.title)
  let [content, setContent] = useState<string>(modifyBoardData.content)

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

      .catch(function(error) {
        navigate('/error/404')
        console.log(error)
      })
  }, [])

  useEffect(() => {
    setTitle(modifyBoardData.title)
  }, [modifyBoardData.title])

  useEffect(() => {
    setContent(modifyBoardData.content)
  }, [modifyBoardData.content])

  return (
    <div className="board-modify">
      <Title children="Write content"/>

      <form>
        <div>
          <Label htmlFor="title">Title</Label>
          <Input type="text" id="title" value={title || ""} onChange={(e) => setTitle(e.target.value)} placeholder="제목을 입력해주세요."/>
        </div>

        <div>
          <Label htmlFor="content">Content</Label>
          <Textarea name="content" id="content" value={content || ""} onChange={(e) => setContent(e.target.value)} placeholder="내용을 입력해주세요."/>
        </div>
      </form>

      <div className="grid-3">
        <Button children="Delete" variant="danger" onClick={formDelete}/>
        <Button children="Confirm" variant="primary" onClick={formSubmit}/>
        <Button children="Cancel" variant="secondary" onClick={formCancel}/>
      </div>
    </div>
  )
}

export default BoardModify

 

2. axios.patch()로 서버 데이터 수정하기

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

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

 

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

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

 

Postman을 통해서 PATCH로 수정한 데이터를 확인할 수 있다.

 

 

  • src/pages/board/modify/index.tsx
  1. 확인(Confirm) 버튼을 누를 때 데이터가 수정되어야 하기 때문에 formSubmit() 클릭 이벤트를 만든다.
  2. 빈 값을 전송하면 안 되기 때문에 if문을 통해 length가 0일 때 alert 창이 나오게 만든다.
  3. 수정 페이지는 서버에 데이터를 수정해야 하기 때문에 patch() 메서드를 사용한다.
  4. patch() 안에 전송할 데이터의 key와 value를 작성한다. (title, content, updated_at)
const BoardModify = () => {
  // hook
  const params = useParams().id
  const navigate = useNavigate()

  // state
  let [modifyBoardData, setModifyBoardData] = useState<any>([])
  let [title, setTitle] = useState<string>(modifyBoardData.title)
  let [content, setContent] = useState<string>(modifyBoardData.content)

  const formSubmit = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()

    if(title.length === 0) {
      alert('제목을 입력해 주세요.')
    } else if(content.length === 0) {
      alert('내용을 입력해 주세요.')
    } else {
      if(window.confirm('게시글을 수정하시겠습니까?')) {
        axios.patch(`http://localhost:3001/board/${params}`, {
          title: title,
          content: content,
          updated_at: new Date()
        })
          .then(function(response) {
            alert('게시글이 수정되었습니다.')
            navigate('/board')
          })

          .catch(function(error) {
            console.log(error)
          })
      } else {
        return false
      }
    }
  }

  ...

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

export default BoardModify

 

3. axios.delete()로 서버 데이터 삭제하기

  • src/pages/board/modify/index.tsx
  1. 삭제(Cancel) 버튼을 누를 때 데이터가 삭제되어야 하기 때문에 formDelete() 클릭 이벤트를 만든다.
  2. 취소(Cancel) 버튼을 누르면 게시판 목록 페이지로 갈 수 있게 formCancel() 클릭 이벤트를 만든다.
const BoardModify = () => {
  ...
  
  const formDelete= (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()

    if(window.confirm('게시글을 삭제하시겠습니까?')) {
      axios.delete(`http://localhost:3001/board/${params}`, {
      })
        .then(function(response) {
          alert('게시글이 삭제되었습니다.')
          navigate('/board')
        })

        .catch(function(error) {
          console.log(error)
        })
    } else {
      return false
    }
  }

  const formCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()

    if(window.confirm('게시글 수정을 취소하시겠습니까?')) {
      navigate('/board')
    } else {
      return false
    }
  }

  ...

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

export default BoardModify

 


전체 코드

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

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

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

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

  // state
  // TODO :: any 타입 수정
  let [modifyBoardData, setModifyBoardData] = useState<any>([])
  let [title, setTitle] = useState<string>(modifyBoardData.title)
  let [content, setContent] = useState<string>(modifyBoardData.content)

  const formSubmit = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()

    if(title.length === 0) {
      alert('제목을 입력해 주세요.')
    } else if(content.length === 0) {
      alert('내용을 입력해 주세요.')
    } else {
      if(window.confirm('게시글을 수정하시겠습니까?')) {
        axios.patch(`http://localhost:3001/board/${params}`, {
          title: title,
          content: content,
          updated_at: new Date()
        })
          .then(function(response) {
            alert('게시글이 수정되었습니다.')
            navigate('/board')
          })

          .catch(function(error) {
            console.log(error)
          })
      } else {
        return false
      }
    }
  }

  const formDelete= (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()

    if(window.confirm('게시글을 삭제하시겠습니까?')) {
      axios.delete(`http://localhost:3001/board/${params}`, {
      })
        .then(function(response) {
          alert('게시글이 삭제되었습니다.')
          navigate('/board')
        })

        .catch(function(error) {
          console.log(error)
        })
    } else {
      return false
    }
  }

  const formCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault()

    if(window.confirm('게시글 수정을 취소하시겠습니까?')) {
      navigate('/board')
    } else {
      return false
    }
  }

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

      .catch(function(error) {
        navigate('/error/404')
        console.log(error)
      })
  }, [])

  useEffect(() => {
    setTitle(modifyBoardData.title)
  }, [modifyBoardData.title])

  useEffect(() => {
    setContent(modifyBoardData.content)
  }, [modifyBoardData.content])

  return (
    <div className="board-modify">
      <Title children="Write content"/>

      <form>
        <div>
          <Label htmlFor="title">Title</Label>
          <Input type="text" id="title" value={title || ""} onChange={(e) => setTitle(e.target.value)} placeholder="제목을 입력해주세요."/>
        </div>

        <div>
          <Label htmlFor="content">Content</Label>
          <Textarea name="content" id="content" value={content || ""} onChange={(e) => setContent(e.target.value)} placeholder="내용을 입력해주세요."/>
        </div>
      </form>

      <div className="grid-3">
        <Button children="Delete" variant="danger" onClick={formDelete}/>
        <Button children="Confirm" variant="primary" onClick={formSubmit}/>
        <Button children="Cancel" variant="secondary" onClick={formCancel}/>
      </div>
    </div>
  )
}

export default BoardModify

 

#5
axios.patch()로 서버 데이터를 수정하고,
axios.delete()로 서버 데이터를 삭제했다.

+ Recent posts