**
들어가기
useMutation: client가 backend와 통신하기 위해 필요한 공통적으로
거쳐야 하는 과정을 담아놓음. POST로 통신할떄,
GET으로 통신할떄는 useSWR을 사용.
withHandler: backend의 api들을 코딩하는 과정에서 공통적으로 필요한
과정을 담아놓음. NextJs는 개별적으로 움직이기 때문에, 공통적으로 쓰이는 부분을
만들어 놓음.
libs안에 client/server 두개의 폴더를 만들어서 client에는 server에서 사용되는 API
server에는 backend의 API에서 공통적으로 사용되는 API를 담아둠.
**
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!!!
엄청 어렵고 햇갈리니까 마르고 닳도록 볼것.
어려우면 무조건 외워버릴것~~
/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으로 만들어 놓은것
코드기 어려워서 마르고 닳도록 보자!!