일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- java
- tanstackquery
- go
- css
- hook
- springboot
- satisfiles
- 오블완
- JavaSpring
- Gin
- JPA
- backend
- frontend
- 웹애플리케이션서버
- 티스토리챌린지
- RTK
- component
- golang
- designpatterns
- React
- Spring
- Chakra
- javascript
- Redux
- react-hook-form
- storybook
- typescript
- test
- ReactHooks
- Today
- Total
bkdragon's log
변신하는 Form 본문
오랜만의 글이다! 최근에 취업에 성공해 바쁘게 살고 정신없이 살다보니 소홀해진 것 같다. 공부는 꾸준하게 하고 있다.
오늘은 변신가능한 폼을 만들어서 소개해보려고 한다. 페이지를 사용하다 보면 다양한 형태의 폼을 만날 수 있다. 처음 페이지를 들어가서 거의 바로 회원가입 폼과 로그인 폼을 만날 텐데 이 둘만 하더라도 약간의 형태가 바뀐다. 프론트엔드 개발자로서 이런 것들을 한번에 처리하고 싶은 욕구가 생겨서 만들어보게 되었다!
물론! 로그인 폼, 회원가입 폼, 글 작성 폼 등 책임을 세분화하여 하는 것이 좋다. (코드를 이해하는 면에서도 그렇다 내가 짜서 잘 모르겠지만 어쪄면 변신 폼은 약간 어렵고 난해한 코드일 수 있다.)
포인트는 다음과 같다.
1. context api 없는 합성 컴포넌트
2. 비제어 컴포넌트
포인트를 생각하며 코드를 보자.
import React, { PropsWithChildren } from 'react';
import CompoundInput, { CompoundInputProps } from './CompoundInput';
interface CompoundFormProps {
onSubmit: () => void;
}
const CompoundForm: React.FC<PropsWithChildren<CompoundFormProps>> & {
Input: React.FC<CompoundInputProps>;
} = ({ children, onSubmit }) => {
return <form onSubmit={onSubmit}>{children}</form>;
};
CompoundForm.Input = CompoundInput;
export default CompoundForm;
폼을 제출하는 함수는 외부로부터 받아오고 있다. 이 폼을 사용하는 컴포넌트에서 사용할 데이터의 형태가 결정되기 때문이다.
Input 컴포넌트의 코드도 확인해보자.
import React from 'react';
import { UseFormRegisterReturn, FieldErrors } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';
export interface CompoundInputProps {
register: UseFormRegisterReturn<string>;
name: string;
errors: FieldErrors;
style?: React.CSSProperties;
}
const CompoundInput: React.FC<CompoundInputProps> = ({
register,
errors,
name,
style,
}) => {
return (
<div>
<input {...register} style={style} />
<ErrorMessage
errors={errors}
name={name as unknown as any}
render={({ messages }) =>
messages &&
Object.entries(messages).map(([type, message]) => (
<p key={type} style={{ color: 'red' }}>
{message}
</p>
))
}
/>
</div>
);
};
export default CompoundInput;
react hook form 에서 제공하는 register 등을 props로 받아온다. 일일히 상태를 만들지 않고 비제어 컴포넌트 형식으로 폼을 제출하려고 이 방식을 택했다. 검증이 편한건 덤이다.
이제 이렇게 작성한 컴포넌트를 아래처럼 사용할 수 있다. 우선은 이메일과 패스워드만 존재하는 폼이 경우이다.
const TestForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<{ email: string; password: string }>();
const onSubmit = (data: { email: string; password: string }) => {
console.log(data);
};
return (
<div>
<CompoundForm onSubmit={handleSubmit(onSubmit)}>
<CompoundForm.Input
register={register('email', { required: '입력요망' })}
name="email"
errors={errors}
/>
<CompoundForm.Input
register={register('password')}
name="password"
errors={errors}
/>
</CompoundForm>
</div>
);
};
onSubmit 은 완벽하게 구현은 안되어있다. 비동기 코드가 들어가게 될 것이다. 이제 여기서 name 이라는 값이 추가된다면
useForm에 타입 수정해주고 Compound.Input 추가해주고 하면 끝이다. 변화하는 폼의 완성이다.
'concept' 카테고리의 다른 글
ws와 was (0) | 2024.10.26 |
---|---|
에러 헨들링에 관하여 (0) | 2024.06.14 |
CSS 프레임워크로 atomic design pattern 적용하기 (0) | 2023.09.02 |
[Redux-toolkit] 비동기 처리하기 (0) | 2023.09.01 |
flex-item (0) | 2023.08.30 |