[React] Write 컴포넌트와 EditForm 컴포넌트 합치기

아아 끝없는 리팩토링아

react의 기초 정도만 아는 상태에서 CURD를 구현하다보니 게시판 글을 update하는 방법으로 선택한 것이 write 컴포넌트와 똑같이 생긴 editForm 컴포넌트를 추가로 생성하는 것 이었다.

그땐 몰랐었죠(진짜 몰랐음) <중복되는 컴포넌트/로직은 재사용하기> 이 방법을 ㅎ

onEdit

const { gameNo } = useParams()
const [editing, setEditing] = useState(null)

<Button onClick={onEdit}>수정</Button>

const onEdit = async () => {
    const games = await baseApi(`/games/${gameNo}`)
    
    setEditing(games.data)
   
    if (editing) {
      history.push({
        pathname: `/pages/writing`,
        state: editing,
       
      })
    }
  }

우선 수정 버튼을 눌렀을 때 기존 데이터가 글쓰기 페이지에 들어가는 작업부터 진행했다.
useState를 이용해 해당 게임의 정보를 저장하고 history.push에 state 값을 포함, 전송해 주었다.

history에 저장해서 보낸 정보는 해당 컴포넌트에서 useLocation()을 통해 확인할 수 있다.

const location = useLocation()

 console.log(location)
 

if (location.state) {
    const prevData = location.state
    const { title, genderType, historyType, ageType, content, court, courtNo } = prevData
    form.setFieldsValue({
      title: title,
      genderType: genderType,
      historyType: historyName[historyType],
      ageType: ageType === 0 ? '무관' : ageType + '대',
      content: content,
      court: court.name,
      courtNo: courtNo,
    })
  }

ant-design을 쓰고 있기 때문에 form.setFieldsValue로 value 값을 넣어 주었다.

[ant-design으로 form 만들기 참고]
https://velog.io/@storyno7/5%EC%A3%BC%EC%B0%A8-reactAnt-design%EC%9C%BC%EB%A1%9C-form-%EB%A7%8C%EB%93%A4%EA%B8%B0

Write.js

문제는 발행하기 버튼을 눌렀을 때 데이터가 create로 가는지 update로 가는지 구분해 주어야 한다는 것 이었다.

api.js

일단 너무나도 긴 api를 따로 api.js 컴포넌트로 분리해 주었다.

import { createList, updateList } from 'service/api'

const handleCreateSuccess = (formData) => {
    createList(formData)
  }

const handleUpdateSuccess = (gameNo, formData) => {
    updateList(gameNo, formData)
  }

<Writing onSubmitSuccess={handleCreateSuccess} /> //글쓰기 페이지
<DetailMain onUpdateSuccess={handleUpdateSuccess} /> //수정버튼이 있는 페이지

그리고 각각의 컴포넌트에 props로 전송해준다.

Writing.js

const Writing = ({ onSubmitSuccess }) => {
  const location = useLocation()
  const [form] = Form.useForm()


  const onFinish = (values) => {
    onSubmitSuccess(values)
  } 
  //createList로 전송

Writing 컴포넌트에 onSubmitSuccess로 전송된 함수는 onfinish를 통해 발행된다. 그럼 updateList는 어떻게 되는 것일까. 일단 Writing의 onSubmitSuccess를 기억해두자.

Detail.js

const DetailMain = ({ onUpdateSuccess }) => {
  const history = useHistory()
  
  const handleSubmitSuccess = (values) => {
    onUpdateSuccess(values)
  }

Detail 로 보내진 onUpdateSuccess는 handleSubmitSuccess을 통해 전송되는데 이때 이 handleSubmitSuccess 함수는 history.push를 통해 onSubmitSuccess의 이름으로 Write 컴포넌트에 보내지는 것이다.

 const onEdit = async () => {
    const games = await baseApi(`/games/${gameNo}`)
    setEditing(games.data)
    if (editing) {
      history.push({
        pathname: `/pages/writing`,
        state: editing,
        **onSubmitSuccess: handleSubmitSuccess,**
      })
    }
  }

이후 Write 컴포넌트에서 location을 사용해 onSubmitSuccess를 바꾸어주면 하나의 버튼으로 두가지 함수를 제어할 수 있다.

 if (location.onSubmitSuccess) {
    onSubmitSuccess = location.onSubmitSuccess
  }

  const onFinish = (values) => {
    onSubmitSuccess(values)
  }

++ 그리고 마지막까지 updateList에 gameNo를 보내주는 방법에 대해 고민했는데

const { gameNo } = useParams()

  const handleSubmitSuccess = (values) => {
    onUpdateSuccess(`${gameNo}`, values)
  }

이미 useParams로 gameNo를 저장하고 있었기 때문에 함수에 ${gameNo} 만 추가해주면 문제없이 동작하더라.

쓰고보니 간단한데 컴포넌트 통합하는데 2박 3일 걸렸다..헤헤..

좋은 웹페이지 즐겨찾기