본문 바로가기

코딩/NextJs

당근마켓 4 :Refactoring

728x90

react hook form의 여러가지 기능 

https://react-hook-form.com/api/useform/formstate/

 

validate
유효성을 검사할 인수로 콜백 함수를 전달하거나 콜백 함수의 개체를 전달하여 모든 유효성을 검사할 수 있습니다.
```
< input
{...register("test", {
validate: value => value === '1'
})}
/ >
```
https://react-hook-form.com/api/useform/register/

mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'
이 옵션을 사용하면 사용자가 form을 제출하기 전에 유효성 검사를 할 수 있습니다(onSubmit 이벤트).
https://react-hook-form.com/api/useform#props

onTouched
유효성 검사는 첫 번째 blur 이벤트에서 트리거됩니다. 그 후에는 모든 change 이벤트에서 트리거됩니다.

all
blur 및 change 이벤트에서 유효성 검사가 트리거됩니다.

 

This option allows you to configure the validation strategy before a user submits the form that is happened during onSubmit event by invoking handleSubmit function.

NameTypeDescription

onSubmit string Validation will trigger on the submit event and inputs will attach onChange event listeners to re-validate them.
onBlur string Validation will trigger on the blur event.
onChange string Validation will trigger on the change event with each input, and lead to multiple re-renders. Warning: this often comes with a significant impact on performance.
onTouched string Validation will trigger on the first blur event. After that, it will trigger on every change event.
Note: when using with Controller, make sure to wire up onBlur with the render prop.
all string Validation will trigger on the blur and change events.

https://react-hook-form.com/api/useform/#props

blur An element looses focus

setError()


이 함수를 사용하면 하나 이상의 오류를 수동으로 설정할 수 있습니다.
```
setError("username", {
type: "manual",
message: "Dont Forget Your Username Should Be Cool!"
});
```
https://react-hook-form.com/api/useform/seterror


reset()

전체 form state 또는 form state의 일부를 리셋합니다.
(form에서 submit후, 전체 input 초기화할 때 사용 가능)
https://react-hook-form.com/api/useform/reset


resetField


개별 field state를 재설정합니다.
(form에서 submit후, 특정 input만 초기화할 때 사용 가능)
https://react-hook-form.com/api/useform/resetfield

 

 

WATCH로 FORM이 작동하는지 확인하기


EMAIL INPUT에 적었던게 PHONE에서 적었을 때도 남아있음 클릭 시 RESET()하도록 사용함

onValid하면
 fetch하여 api를 호출해 data를 보내줌
request.body 하면 내용이 나오지만 
request.body.email하면 안나옴 프론트엔드에서 header 설정해줘야함 
headers:{

   "Content-Type":"application/json"

}
Post 요청만 받도록 . 

 

Uploading JSON data

POST프로토콜로 JSON인코딩된 데이터를 보내기 위해 fetch()를 사용합니다.
body의 데이터 유형은 반드시 "Content-Type" 헤더와 일치해야 함
```
await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE 등
body: JSON.stringify(data), // data can be `string` or {object}!
headers:{
'Content-Type': 'application/json'
}
})
```
https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch#uploading_json_data

 

 const [loading, setLoading] = useState(false);
  const [data, setData] = useState<undefined | any>(undefined);
  const [error, setError] = useState<undefined | any>(undefined);

-->clean code

interface UseMutationState {
  loading: boolean;
  data?: object;
  error?: object;
}

const [state, setSate] = useState<UseMutationState>({
    loading: false,
    data: undefined,
    error: undefined,
  });

------------------------------------------------------------


import { useState } from "react";

interface UseMutationState {
  loading: boolean;
  data?: object;
  error?: object;
}
type UseMutationResult = [(data: any) => void, UseMutationState];

export default function useMutation(url: string): UseMutationResult {// typescript return타입 지정해야함
  const [state, setSate] = useState<UseMutationState>({
    loading: false,
    data: undefined,
    error: undefined,
  });
  function mutation(data: any) {
    setSate((prev) => ({ ...prev, loading: true }));
    fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),
    })
      .then((response) => response.json().catch(() => {}))
      .then((data) => setSate((prev) => ({ ...prev, data })))
      .catch((error) => setSate((prev) => ({ ...prev, error })))
      .finally(() => setSate((prev) => ({ ...prev, loading: false })));
  }
  return [mutation, { ...state }];
}

 


libs/server/withHandler.ts

import { NextApiRequest, NextApiResponse } from "next";

export default function withHandler(
  method: "GET" | "POST" | "DELETE",
  fn: (req: NextApiRequest, res: NextApiResponse) => void
) {
  return async function (req: NextApiRequest, res: NextApiResponse) {
    if (req.method !== method) {
      return res.status(405).end();
    }
    try {
      await fn(req, res);
    } catch (error) {
      console.log(error);
      return res.status(500).json({ error });
    }
  };
}

import { NextApiRequest, NextApiResponse } from "next";
import client from "../../../libs/server/client";
import withHandler from "../../../libs/server/withHandler";

async function handler(req: NextApiRequest, res: NextApiResponse) {
  console.log(req.body);
  return res.status(200).end();
}

export default withHandler("POST", handler);



helper function
nextJS에서 api route 만들 때는 그 function을 export default 해야함아니면 api 호출시 function 작동 아니함. 
nextJS가  실행할 function을 retunr하는 ㄹfunction을 만드는 것

 https://medium.com/@la.place/higher-order-function-%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-1c61e0bea79

일일히 NextApiRequest, NextApiResponse 작성하시기보다 NextApiHandler 이용하셔도 됩니당.

mport { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';

export const withHandler = (
  method: 'GET' | 'POST',
  handler: NextApiHandler,
): NextApiHandler => {
  return async (req, res) => {
    if (req.method !== method) {
      res.status(405).end();
    }

    try {
      await handler(req, res);
    } catch (error) {
      console.error(error);
      if (error instanceof Error) {
        res.status(500).json({ error: error.message });
      } else {
        res.status(500).json({ error: 'Internal Server Error' });
      }
    }
  };
};
express(유튜브 클론코딩) 할 때도 나오는 내용인데요. 실질적으로 res.json()이나 res.status(200).end() 얘네들 자체가 return이 void 입니다.
(property) json: (body: any) => void
return을 붙여주는 이유는 명확하게 여기가 끝나는 곳이다 라는 표시를 해주려고 붙이는거구요. 사실상 return res.json()은 아래와 같습니다.
return void; = return;
아무것도 리턴하지 않고 있는게 맞죠???
그래서 return res.json()이 아니라 res.json() 라고 써도 동작합니다. 근데 IDE의 도움을 좀 더 받고싶다면 return을 무조건 붙이는게 더 좋은 것 같더라구요. 물론 여러 다른 이유도 있구요

 

path수정하기 

../../libs 
.../../../components 
tsconfig.json
   "baseUrl": ".",
    "paths": {
      "@libs/*": ["libs/*"],
      "@components/*": ["components/*"]
    }
tsconfig수정후에는 서버종료후 재시작해야함 
edit> replace in files 
정규표현식으로 바꿔서 


baseUrl
기본 디렉토리를 설정할 수 있습니다. (루트 폴더를 정의할 수 있습니다.)
이 프로젝트 내에서 "baseUrl": "./"을 사용하면 TypeScript는 tsconfig.json과 동일한 폴더에서 시작하는 파일을 찾습니다. "../" 또는 "./"로 파일을 import해오는 것이 지겹다면 이 문제를 해결할 수 있는 좋은 방법입니다.
https://www.typescriptlang.org/tsconfig#baseUrl

paths
파일을 import해오는 경로를 다시 매핑합니다. 이 패턴은 코드베이스 내에서 긴 상대 경로를 피하는 데 사용할 수 있습니다.
```
"paths": {
"app/*": ["app/*"],
"config/*": ["app/_config/*"],
"environment/*": ["environments/*"],
"shared/*": ["app/_shared/*"],
"helpers/*": ["helpers/*"],
"tests/*": ["tests/*"]
},
```
https://www.typescriptlang.org/tsconfig#paths

tsconfig 설정 옵션
https://www.typescriptlang.org/tsconfig

 

 

 

 

 

'코딩 > NextJs' 카테고리의 다른 글

당근마켓 :6 Authorization  (0) 2023.04.11
당근마켓 5 : authentication  (0) 2023.04.03
당근마켓 3: database setup  (0) 2023.03.29
당근마켓 2:Tailwind css  (0) 2023.03.17
당근마켓 :1 NextJs, Tailwind setup  (0) 2023.03.15