728x90
반응형
혹시 antd form을 사용 중이라면 이 글에서 답을 찾을 수 있다. 아니라면 다른 글로.. bye
❌ 문제 상황
게시글이 작성완료되었을때, 게시글 작성 textarea의 값이 초기화되도록 한다.
하지만, react-hook-form에서 제공하는 reset() 함수가 작동하지 않음
😅 문제 코드
import { InboxOutlined, UploadOutlined } from '@ant-design/icons';
import { Button, Form, Input, Space, Upload } from 'antd';
import { useDispatch, useSelector } from 'react-redux';
import { addPostRequest } from '../reducers/post';
import { useCallback, useEffect } from 'react';
import { useForm } from 'react-hook-form';
const { TextArea } = Input;
const PostForm = () => {
const dispatch = useDispatch();
const addPostDone = useSelector(state => state.post.addPostDone);
const { register, getValues, control, reset } = useForm(); //👈
useEffect(() => {
if (addPostDone) {
reset({ content: '' }); //👈
}
}, [addPostDone, reset]);
const onSubmit = useCallback(() => {
const { content } = getValues();
dispatch(addPostRequest(content));
}, [dispatch, control, getValues]);
return (
<Form
name="postForm"
onFinish={onSubmit}
>
<Form.Item label="TextArea" name="content">
<TextArea rows={4} {...register('content')} /> //👈
</Form.Item>
<Form.Item
wrapperCol={{
span: 12,
offset: 6,
}}
>
<Space>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Space>
</Form.Item>
</Form>
);
};
export default PostForm;
reset() 공식 문서에 하란대로 했는데, 안되는 것이다.
🪴 원인
antd로 상태관리를 하고 있는건데, 갑자기 react-hook-form으로 reset를 시도하고 있던 것.
antd와 react-hook-form의 역할이 동일한데, 같이 사용할 이유가 없다. 하나만 써도 충분.
antd와 react-hook-form은 각각 독립적으로 폼 관리 기능을 제공하는 라이브러리리다.
따라서 두 라이브러리 간에는 리셋 기능을 위한 메서드가 다를 수 있다.
react-hook-form의 reset 메서드는 react-hook-form 라이브러리가 제공하는 메서드로, useForm 훅에서 반환된 reset 함수를 사용하여 폼 필드의 값을 초기화할 수 있다.
반면에 antd의 Form 컴포넌트는 독립적인 폼 관리 기능을 제공하며, resetFields 메서드를 사용하여 폼 필드를 리셋한다.
이 메서드는 antd의 Form 컴포넌트의 인스턴스에서 호출되어야 한다.
따라서 antd와 react-hook-form을 함께 사용할 때는, reset 메서드와 resetFields 메서드가 서로 다른 기능을 수행한다는 점을 인지해야 한다.
antd를 사용하는 경우, Form 컴포넌트의 참조를 생성하고 resetFields 메서드를 호출하여 폼을 리셋하는 방식으로 폼을 초기화할 수 있다.
이런 실수를! 양자택일 극단적이야 넌~
🕊 해결 코드
react-hook-form을 지우고 antd form기능으로 대체했다.
import { InboxOutlined, UploadOutlined } from '@ant-design/icons';
import { Button, Form, Input, Space, Upload } from 'antd';
import { useDispatch, useSelector } from 'react-redux';
import { addPostRequest } from '../reducers/post';
import { useCallback, useEffect } from 'react';
const { TextArea } = Input;
const PostForm = () => {
const dispatch = useDispatch();
const addPostDone = useSelector(state => state.post.addPostDone);
const [form] = Form.useForm(); //👈
useEffect(() => {
if (addPostDone) {
form.resetFields(); //👈
}
}, [addPostDone]);
const onSubmit = useCallback(() => {
const content = form.getFieldValue('content'); //👈
dispatch(addPostRequest(content));
}, []);
return (
<Form
name="postForm"
{...formItemLayout}
onFinish={onSubmit}
style={{
maxWidth: 600,
}}
form={form} //👈
>
<Form.Item label="TextArea" name="content" rules={[{ required: true }]}>
<TextArea rows={4} />
</Form.Item>
<Form.Item
wrapperCol={{
span: 12,
offset: 6,
}}
>
<Space>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Space>
</Form.Item>
</Form>
);
};
export default PostForm;
728x90
반응형