[TIL] Form Validation - 2

ohoho·2024년 11월 26일

슬기로운스터디

목록 보기
49/54

오늘 공부한것 & 기억할 내용

InputHTMLAttributes

  • input을 컴포넌트로 만들어 여러개의 props를 필요로 할때 props를 일일이 적지 않고 사용할 수 있다.
interface IInput{
    errors?:string[];
    name:string
}  

export default function Input({errors,name, ...extraProps}:IInput & InputHTMLAttributes<HTMLInputElement>){
  <input
   name={name}
  {...extraProps}
  />
})

coerce

  • form 검증에서 유효성 검사를 진행할때 input안에 들어가는건 모두 string으로 변환된다.(검증하는 함수 안에 formData가 들어가면 자동으로 string으로 변함) 그래서 z.number()를 사용하면 작동되지 않기에 coerce를 사용한다.
  • coerce는 유저가 입력한 string을 number로 변환하려 시도한다.
//action.ts
const tokenSchema = z.coerce.number()
export async function smsLogin(prev:any,formData:FormData) {
   //여기 들어오는 formData가 모두 string으로 변환됨 
}

validator

  • 정규식 검사를 도와주는 도구
//두개 다 똑같은 기능이지만 코드만 조금 다름
const phoneSchema = z.string().trim().refine(validator.isMobilePhone,"Wrong phone format")
//특정 지역 번호만 인증 가능하도록 구현 가능
const phoneSchema = z.string().trim().refine(phone => validator.isMobilePhone(pnone,"ko_KR"))

배운점 & 느낀점

serverAction을 사용하면서 useActionState에서 애를 먹었다. Next15,react19 버전에선 useFormState를 사용하지 못해서 useActionState을 사용하였더니 버튼을 눌렀을때 입력값이 틀린경우 기존에 작성했던 input의 내용이 모두 사라지는 이슈가 발생했다. 강의랑 버전이 다르게 최신버전을 사용하니 이런 이슈들이 발생하는데 단순히 버전을 내리면 문제는 해결되지만 실무에선 버전을 어떻게 쓸지 모르기에 해결을 했지만 버전을 내리는게 좋은건지 문제를 해결하는게 좋은건지는 잘 모르겠다.

문제
버튼을 눌렀을때 입력값이 틀린경우 기존에 작성했던 input의 내용이 모두 사라지는 이슈가 발생했다.

해결
1. action.ts에서 유효성 검사 성공하지 못할시 form데이터를 저장하도록 작업하였다.
2. input에 defaultValue를 작성하여 기본값을 넣어주었다.

//action.ts
const form = {
  email:formData.get("email") as string,
  username:formData.get("username") as string,
  password:formData.get("password") as string
}
if(!result.success){
  return {
    fieldErrors:result.error.flatten().fieldErrors,
    //성공하지 못할시 form데이터 저장
    form,
    success:false
  }
}else{
  return {
    //성공 할 시 form데이터 초기화
    form: { email: "", username: "", password: "" },
    fieldErrors: {},
    success:true
  }
}

//page.tsx
const [state,action] = useActionState(onSubmit,{
    form: { email: "", username: "", password: "" },
    fieldErrors: {},
    success:false
})

<Input name="email" type="email" placeholder="Email" required defaultValue={state?.form?.email}/>

위 문제의 다른 사람의 해결 방법

  • 코드리뷰 중 다른 사람이 나와 같은 문제 해결한것을 발견
  • 처음엔 나와 비슷하게 해결했으나 보안을 생각하여 useState로 구현하심
//page.tsx
const [formInput, setFormInput] = useState({
		email: '',
		username: '',
		password: '',
});

const onInputChange = (ev: ChangeEvent<HTMLInputElement>) => {
  const {
    currentTarget: { name, value },
  } = ev;
  if (!(name in formInput)) {
    return;
  }

  setFormInput((prevInput) => ({ ...prevInput, [name]: value }));
};
<FormInput
label='Email'
placeholder='email'
name='email'
type='email'
value={formInput.email}
onChange={onInputChange}
errorMessage={state?.errors?.fieldErrors.email}
/>

세상은 넓고 천재는 많다.. 더 열심히 공부해야지 ㅠ

0개의 댓글