useMutation, formSubmission, withHandler

김종민·2022년 8월 1일
0

apple-market

목록 보기
12/37

**
들어가기
useMutation: client가 backend와 통신하기 위해 필요한 공통적으로
거쳐야 하는 과정을 담아놓음. POST로 통신할떄,
GET으로 통신할떄는 useSWR을 사용.

withHandler: backend의 api들을 코딩하는 과정에서 공통적으로 필요한
과정을 담아놓음. NextJs는 개별적으로 움직이기 때문에, 공통적으로 쓰이는 부분을
만들어 놓음.

libs안에 client/server 두개의 폴더를 만들어서 client에는 server에서 사용되는 API
server에는 backend의 API에서 공통적으로 사용되는 API를 담아둠.
**

1. libs/client/useMutation.tsx

client에서 backend와 POST로 동신할 떄, 공통적으로 사용되는 부분을
hook으로 만들어 놓음.

import { useState } from 'react'

interface UseMutationState<T> {
  loading: boolean
  data?: T
  error?: object
}
///UseMutationState interface를 만들어줌.

type useMutationResult<T> = [(data?: any) => void, UseMutationState<T>]
///useMutationResult type은 함수와 UseMutationState의 배열임
///어려우면 그냥 외우자 ㅠㅠ

export default function useMutation<T = any>(
  url: string
): useMutationResult<T> {
///typescript라 type을 적어주는게 무척 어려움.
///useMutation의 type은 <T=any>임.
///url: string을 argument로 받음.
///returnType은 useMutationResult<T>로 적어주고
///윗부분은 type useMutaionResult<T>를 만들어줌.

  const [state, setState] = useState<UseMutationState<T>>({
    loading: false,
    data: undefined,
    error: undefined,
  })
  ///state의 defult값을 설정해줌, loading, data, error
  
  function mutation(data?: any) { ///mutation함수릏 실행, 나중에 return해줌.
    setState((prev) => ({ ...prev, loading: true })) ///loading시작.
    fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data), ///front에서 보내온 data
    })
      .then((response) => response.json().catch(() => {}))
      ///빋아온 url(ex./apl/users/me)에 fetch로 data을 보내서
      ///response을 받아서 json()함. 읽을 수 있도록.
      
      .then((data) => setState((prev) => ({ ...prev, data })))
      ///response에 data가 있으면, data를 setState에 담아줌.
      
      .catch((error) => setState((prev) => ({ ...prev, error })))
      ///혹시 error가 있으면, setState에 담아줌
      
      .finally(() => setState((prev) => ({ ...prev, loading: false }))) 
      ///loading 끝.
  }
  return [mutation, { ...state }]  ///mutation함수와 state를 return함.
}

notice!!!
엄청 어렵고 햇갈리니까 마르고 닳도록 볼것.
어려우면 무조건 외워버릴것~~

2.libs/server/withHandler.ts

/api/~ 아래의 API들에게서 공통적으로 쓰이는 부분을 withHandler로 빼놓음.

import { NextApiRequest, NextApiResponse } from 'next'

export interface ResponseType {
  ok: boolean
  [key: string]: any ///API호출시 응답 type. key:string => ok이외의것 커버함.
}

interface ConfigType {
  method: 'GET' | 'POST' | 'DELETE'
  handler: (req: NextApiRequest, res: NextApiResponse) => void
  isPrivate?: boolean
}
///withHandler 함수가 받는 argument를 ConfigType으로 하나의 object로 만듬.

export default function withHandler({
  method,
  handler,
  isPrivate = true, ///isPrivate의 기본값은 true로, login이 되어있으면 false가 됨
                    ///login여부는 req.session으로 파악 할 예정.
                    ///함수를 다시 return해줌. 한마디로 한번 걸러줌
}: ConfigType) {
  return async function (
    req: NextApiRequest,
    res: NextApiResponse  ///req,res를 받아서 filter를 거치는 함수를 return함.
  ): Promise<any> {
    if (req.method !== method) {  ///'GET', 'POST'가 일치해야 Pass됨.
      return res.status(405).end()
    }
    if (isPrivate && !req.session.user) { ///isPrivate이 true이고 
                                          ///session이 없으면 빠꾸당함.
                                          
    
      return res.status(401).json({ ok: false, error: 'Plz log in' })
    }
    try {
      await handler(req, res) ///위에서 받은 handler함수를 실행시킴.
    } catch (error) {
      console.log(error)
      return res.status(500).json({ error })
    }
  }
}

Notice!!
1. useMutaion은 client에서 server및 database와 통신하기 위해서 사용하는 거고
2. withHandler는 API들에게 공통적으로 적용되는 부분을 hook으로 만들어 놓은것

코드기 어려워서 마르고 닳도록 보자!!

profile
코딩하는초딩쌤

0개의 댓글