https://next.ant.design/components/form-cn/#components -form-demo-form-in-modal
useForm์ ์ง์ ์ฌ์ฉํ์ญ์์ค. ๋๋ ํ์ ๋ ์ด์ด์ ์๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
const CollectionCreateForm = ({ onCancel }) => {
const [์์] = Form.useForm();
form.setFieldsValue({
์นดํ
๊ณ ๋ฆฌ ์ด๋ฆ: caseDetail.categoryName,
});
๋ฐํ (
maskClosable={๊ฑฐ์ง}
title="ํ๋ก์ ํธ ๊ธฐ๋ณธ ์ ๋ณด ์์ "
okText="ํ์ธ"
cancelText="์ทจ์"
onCancel={onCancel}
onOk={() => {
ํํ
.validateํ๋()
.then(๊ฐ => {
form.resetFields();
onCreate(๊ฐ);
})
.catch(์ ๋ณด => {
window.console.log('๊ฒ์ฆ ์คํจ:', ์ ๋ณด);
});
}}
>
์ด useForm์ ์ ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ธฐ๋ฅผ ์ํฉ๋๋ค.
index.js:1 ๊ฒฝ๊ณ : useForm
์ํด ์์ฑ๋ ์ธ์คํด์ค๋ Form ์์์ ์ฐ๊ฒฐ๋์ง ์์์ต๋๋ค. form
prop ์ ๋ฌ์ ์์ผ์
จ์ต๋๊น?
CollectionCreateForm์์ ....
const [์์] = Form.useForm();
form.setFieldsValue({
์นดํ
๊ณ ๋ฆฌ ์ด๋ฆ: caseDetail.categoryName,
});
| ํ๊ฒฝ | ์ ๋ณด |
|---|---|
| ๊ฐ๋ฏธ | 4.0.0-rc.5 |
| ๋ฐ์ | 16.8.6 |
|์์คํ
|mac10.15.3 |
| ๋ธ๋ผ์ฐ์ | ํฌ๋กฌ |
๊ณต์ ํํ์ด์ง์ ๋ฐ๋ผ ์ง์ ์๋๋ฐ ์ด ์ค๋ฅ๊ฐ ์ฌ๊ธฐ์ ๊ธฐ์ ๋ณด๊ณ ๋์ด ํ ๋ง์ ์์์ต๋๋ค.
@LamTech๋, ์๋
ํ์ธ์. https://u.ant.design/codesandbox-repro ๋๋ ์ต์ํ์ GitHub ์ ์ฅ์๋ฅผ ๋ถ๊ธฐํ์ฌ ์จ๋ผ์ธ ๋ณต์ ๋ฅผ ์ ๊ณตํ์ธ์. Need Reproduce
๋ ์ด๋ธ์ด ์ง์ ๋ ๋ฌธ์ ๋ 7์ผ ๋์ ํ๋์ด ์์ผ๋ฉด ์ข
๋ฃ๋ฉ๋๋ค. .
@LamTech๋ , ์๋ ํ์ธ์. ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋ ์ ์๋๋ก ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ฌ ์ฝ๋์๋๋ฐ์ค
ํต์ฌ์ ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ง๋ง ์ด ์ค๋ฅ ๊ฒฝ๊ณ ๋ฅผ ๊ณ์ ๋ณด๊ณ ํ๋ค๋ ๊ฒ์ ๋๋ค.
์ฌ๊ธฐ์์๋ ๋์ผํ ๋ฌธ์ ๊ฐ ์์ง๋ง ์ฝ๋์๋๋ฐ์ค์์ ์ฌํํ์ง ๋ง์ญ์์ค.
+1
๋ชจ๋ฌ์ forceRender ์์ฑ ์ถ๊ฐ
setFieldsValue ๋ฉ์๋์ ์ง์ฐ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
form.resetFields()๋ฅผ ํธ์ถํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋ก์ปฌ์์ ์์๋ http://localhost :8001/components/form-cn/#components-form-demo-form-context๊ฐ ๋ณด๊ณ ๋ฉ๋๋ค.
+1
์ด ๊ฒฝ๊ณ ๋ setFieldsValue๋ฅผ ์ฌ์ฉํ ๋ ํ์๋์ง๋ง ์ํํ๊ฒ ํ์๋ ์ ์์ต๋๋ค.
useForm์ ์ธ์คํด์ค๋ฅผ ์ ๋ฌํ์ต๋๋ค.
Modal์ Form์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๋๋ง๋์ง ์์ต๋๋ค. @se7en00๋ ์ ๋ต๊ธ์ ์ฐธ๊ณ ํ์ฌ Modal์ forceRender
๋ฅผ ์ถ๊ฐ ํ์๋ฉด ๋ฉ๋๋ค. ๋๋ Modal์ด ํ์๋๊ณ ๋ ๋๋ง์ด ์๋ฃ๋ ํ setFieldsValue
๋ฐ resetFields
ํธ์ถํฉ๋๋ค.
V4 ๋ฒ์ ์ฌ์ฉ์(ํจ์ ์ปดํฌ๋ํธ์ ํํ๊ฐ ์กด์ฌํจ) ์ด ๋ฌธ์ ๋ก ์ดํ๋์ ๊ณ ๋ฏผํ๋ค๊ฐ ๊ฑฐ์ ๋ค์ด๋ ๋ป ํ์ต๋๋ค(์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ์ฌ์ฉ์๋ ์ง์ฅ์ด ์์์ต๋๋ค) ๋ง์ง๋ง์ผ๋ก https://ant.design ์ ์ฝ์์ต๋๋ค. / ๋ฐ https://next.ant.design/Discover ํจ์ ๊ตฌ์ฑ ์์ ๋ฐ ํด๋์ค์์ ํ์ ์ฌ์ฉ์ ์ดํดํ๊ณ ํจ์ ๊ตฌ์ฑ ์์๋ฅผ ๊ตฌ๋ณํด์ผ ํฉ๋๋ค.
useEffect(() => {
๋ฐํ() => {
form.resetFields();
};
})
๋ฐํ()=>{....}์์ ์๋ฉธ์ ์ ๋ฐํ๋ ๊ฒ์ ์ ์ฒด ํจ์ ๊ตฌ์ฑ ์์์
๋๋ค(ํ์ฌ ์์์ด ์๋ฉธ๋๋์ง ์ฌ๋ถ๋ ํ
์คํธ๋์ง ์์).
๋ฌธ์ ์ค๋ช
: destroyOnClose | ๋ซ์ ๋ ๋ชจ๋ฌ์ ์์ ์์๋ฅผ ํ๊ดดํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ false์
๋๋ค. forceRender | Modal์ ํ์ ๋ ๋๋ง, ๊ธฐ๋ณธ๊ฐ์ false์
๋๋ค.
์๋ฃจ์
: Modal์ forceRender=true, destroyOnClose=false, Modal์ด ์๋ฉธ(๋ซํ)๋๋ฉด ์ค๋ฅ๊ฐ ๋ณด๊ณ ๋์ง ์์ต๋๋ค. ์์์ ๋ด๋ถ ์ฝ๋๊ฐ ์คํ๋ ๋ ์ฐพ์ ์ ์์ง๋ง ์
๋ ฅ ์ ์ด ID ๋ฐ๋ณต ๊ฒฝ๊ณ ๊ฐ ๋ณด๊ณ ๋ฉ๋๋ค(์ค๋ฅ๋ณด๋ค ์ฐ์ํจ).
๊ฐ์ ๋ฌธ์ +1
์ฝ๋์ setFieldsValue
๋๋ ๊ธฐํ ๊ธฐ๋ฅ์ด ํฌํจ๋ ๊ฒฝ์ฐ ๋
ธ๋๊ฐ ๋ ๋๋ง๋ ํ์ ํธ์ถํ์ญ์์ค.
useEffect(() => {
form.setFieldsValue({
id: 1
})
}, [])
๋๋
componentDidMount() {
form.setFieldsValue({
id: 1
})
}
๋ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
์์ ์ด๋ ๊ฒ๋ ์ด ๋ฌธ์ ๋ฅผ ์์ ํ ํด๊ฒฐํ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์์์ ์์ฑ์ ์ถ๊ฐํ์ฌ ์์์ ํ๋๊ฐ ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ํ๊ณ ๊ฐ๋ฐ์๊ฐ ๋ค์ ์ฝ๋๋ฅผ ์คํํ ์ง ์ฌ๋ถ๋ฅผ ์ง์ ๊ฒฐ์ ํ๋๋ก ํ ์ ์์ต๋๊น?
์ฌ๊ธฐ์๋ ๋ง์ฐฌ๊ฐ์ง
์์ง ๊ณ ์ ๋์ง ์์๋์?
์์์ ์ธ๊ธํ ๋ชจ๋ ๋ฐฉ๋ฒ์ ์๋ํ์ง๋ง ์๋ํ์ง ์์์ต๋๋ค
Modal์ Form์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๋๋ง๋์ง ์์ต๋๋ค. @se7en00๋ ์ ๋ต๊ธ์ ์ฐธ๊ณ ํ์ฌ Modal์
forceRender
๋ฅผ ์ถ๊ฐ ํ์๋ฉด ๋ฉ๋๋ค. ๋๋ Modal์ด ํ์๋๊ณ ๋ ๋๋ง์ด ์๋ฃ๋ ํsetFieldsValue
๋ฐresetFields
ํธ์ถํฉ๋๋ค.
์๋์ ์ฌ์ฉํ ๋ Drawer์๋ forcerender API๊ฐ ์๋๋ฐ Modal๊ณผ ๋ค๋ฅธ ์๋์ API๋ ๊ฐ์ ๋ ๋๋ง์ด ์๋๋ผ ์ฌ์ ๋ ๋๋ง์ ํ๊ณ ๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋๋๋ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์์๊น์? ๋ ๋๋ง์ด ์๋ฃ๋์๋์ง ํ๋จํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น?
๋๋ ํ์๋ค.์๋ก์์ getContainer={false}๋ฅผ ์ฌ์ฉํ๋ฉด ํด๊ฒฐํ ์ ์๋ค.๋ชจ๋ฌ๋ ๋ง์ฐฌ๊ฐ์ง๋ผ๊ณ ์๊ฐํ๋ค.
๋๋ ์๋์์ getContainer={false}๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ชจ๋ฌ์๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ์์ด์ผ ํฉ๋๋ค. ์๋ํด ๋ณผ ์ ์์ต๋๋ค.
useRef๋ฅผ ์ฌ์ฉํ์ฌ Form ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ์์ผ๋ฉฐ, ํผ์ ์ฌ์ฉํ๊ธฐ ์ ์ useRef๊ฐ ์กด์ฌํ๋์ง ํ์ธํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ๊ฐ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์์์ด ํ ๋น๋์์ง๋ง ๊ณ์ ์คํจํฉ๋๋ค.
ํจ๊ณผ์์ ์ง์ form.setFieldsValue๋ฅผ ํธ์ถํ๋ฉด forceRenter๊ฐ ์ถ๊ฐ๋๊ณ Modal์ด ๋ค์ ์ด๋ฆฌ๋๋ผ๋ ์ฌ์ ํ ์ด ๊ฒฝ๊ณ ๊ฐ ํ์๋ฉ๋๋ค.์์ ์๋ฃจ์ ์ ํจ๊ณผ์์ setTimeout(() => form.setFieldsValue, 0)๋ง ๊ฐ๋ฅํฉ๋๋ค.
์๋์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด getContainer={false}๋ฅผ ์ฌ์ฉํ๊ณ ๊ฒฝ๊ณ ๋ฅผ ๋ณด๊ณ ํ์ง ์์๋๋ฐ, ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ์๋ํด๋ณผ ์ ์๊ณ Form ๋ฌธ์์ ๋ช ํํ๊ฒ ์์ฑ๋ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๊ฐ์ฌํฉ๋๋ค ์ด ๋ฐฉ๋ฒ์ผ๋ก ๊ฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค๐
๊ทํ์ ๋ฐฉ๋ฒ์ ์คํ ๊ฐ๋ฅํฉ๋๋ค. ์๋ฆฌ๋ฅผ ์ค๋ช ํ ์ ์์ต๋๊น?
๋ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ Form
๊ฐ ๋ ๋๋ง๋ ๋ useState
๋ก ref
์ ๋ง๋ ๋ค์ ์์ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ref
๋ฅผ ํ์ธํฉ๋๋ค.
interface FormModalProps {
data?: RoleProps;
visible: boolean;
onCancel?: () => void;
onSubmit?: (values: Store) => void;
submitting: boolean;
}
const FormModal: React.FC<FormModalProps> = props => {
const [form] = Form.useForm();
const [formRef, setFormRef] = useState(); // <---- set the ref when Form Rendered
const { data, onSubmit, onCancel, visible, submitting } = props;
// reset Form when modal close
useEffect(() => {
if ( !props.visible && formRef) { // <---- check ref before use the form instance
form.resetFields();
}
}, [props.visible]);
// fill Form when modal open
useEffect(() => {
if (visible && formRef) { // <---- check ref before use the form instance
form.setFieldsValue({
...data,
});
}
}, [props.data]);
// handle form onFinish
const handleFormFinish = (values: Store) => {
if (onSubmit) {
onSubmit(values);
}
};
// handle modal ok
const handleOk = () => {
if (!form) return;
form.submit();
};
return (
<Modal
title="Modal"
confirmLoading={submitting}
onOk={handleOk}
onCancel={onCancel}
visible={visible}
width={640}
>
<Form ref={setFormRef} form={form} onFinish={handleFormFinish}>
<Form.Item name="title" label="Title" >
<Input />
</Form.Item>
</Form>
</Modal>
);
};
๋ ์ด์ ๊ฒฝ๊ณ ๋ ์์ต๋๋ค!
์์ด๋ก ํ ๋ก ํ๊ธฐ ์ด๋ ต๋์?
setFieldsValue๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ค์ ์ฝ๋๋ฅผ ๋์ฒดํ์ฌ ์๋ํด ๋ณด์ญ์์ค(๋ด ์ด๋ฆฌ์์ ์๊ฐ)ใ
<Modal **destroyOnClose** >
<Form **initialValues={formValues}**>
</Form>
</Modal>
๋๋ ๊ทธ๊ฒ์ ์๋ํ๋ค.
์ฒ์์๋ antd ๊ตฌ์ฑ ์์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ์ต๋๋ค.
<Form blabla >
๊ทธ๋ฐ ๋ค์ Form ๊ตฌ์ฑ ์์์ ์์ ์ํ์ ์ถ๊ฐํ์ต๋๋ค.
<Form form={form} blabla >
์ฌ๊ธฐ {form}์ const [form] = Form.useForm();
์์ ์์ต๋๋ค.
Doc(๋ด๊ฐ ํ๋ก์ฐํ๋) -
https://ant.design/components/form/#components -form-demo-form-in-modal
๊ทํ์ ๊ฒฝ์ฐ๋ ๋ค๋ฅผ ์ ์์ต๋๋ค.
https://codesandbox.io/s/form-in-modal-to-create-ant-design-demo-xvcyv
๊ฐ์ ๋ฌธ์ , ๋ชจ๋ ์ ์ฒด๊ฐ ๊ทธ๊ฒ์ ๊ณ ์น ์ ์์ต๋๊น???
์์ linxianxi ์ฐธ์กฐ, https://github.com/ant-design/ant-design/issues/21543#issuecomment -598515368
๋ด๊ฐ ํ ์ ์๋ ๋ชจ๋ฌ
<Modal
destroyOnClose={false}
getContainer={false}
forceRender
>
๋ด๊ฐ ํ ์ ์๋ ๋ชจ๋ฌ
<Modal destroyOnClose={false} getContainer={false} forceRender >
๊ฐ์ฌํฉ๋๋ค. Modal์ forceRender ์ํ์ ์ถ๊ฐํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
const [form] = Form.useForm()
<Form form={form} >
....
</Form>```
this did the trick for me.
๋๋ ๊ทธ๊ฒ์ ์๋ํ๋ค.
์ฒ์์๋ antd ๊ตฌ์ฑ ์์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ์ต๋๋ค.
<Form blabla >
๊ทธ๋ฐ ๋ค์ Form ๊ตฌ์ฑ ์์์ ์์ ์ํ์ ์ถ๊ฐํ์ต๋๋ค.
<Form form={form} blabla >
์ฌ๊ธฐ {form}์
const [form] = Form.useForm();
์์ ์์ต๋๋ค.Doc(๋ด๊ฐ ํ๋ก์ฐํ๋) -
https://ant.design/components/form/#components -form-demo-form-in-modal๊ทํ์ ๊ฒฝ์ฐ๋ ๋ค๋ฅผ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋์๊ฒ๋ ํด๊ฒฐ๋์์ต๋๋ค. ๋๋ ๋ชจ๋ฌ์ด ์๋ ์๋์ ์๋ ํผ์ ์ฌ์ฉํ๊ณ ์์๋ค
๋๋ฅผ ์ํ ๋น๋ฐ ์ฝค๋ณด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
useEffect(() => {
if (์์ && ํ์) {
๋ง์ฝ (ํ์ฌ) {
setTimeout(() => form.setFieldsValue({
...ํ์ฌ์,
}), 0);
} ๋ ๋ค๋ฅธ {
form.resetFields();
}
}
}, [ํ์ฌ์]);
์์ ๊ตฌ์ฑ ์์์ ๋ชจ๋ฌ ๋ฐ ์์ ์ํ ์ ๋ฌ ์์ด ๋์ผํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
https://codesandbox.io/s/basic-usage-ant-design-demo-6llbw?file=/index.js :1618-1661
์์ ๊ตฌ์ฑ ์์์ ๋ชจ๋ฌ ๋ฐ ์์ ์ํ ์ ๋ฌ ์์ด ๋์ผํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
https://codesandbox.io/s/basic-usage-ant-design-demo-6llbw?file=/index.js :1618-1661
๋น์ ์ ์ํ ์์ : https://codesandbox.io/s/basic-usage-ant-design-demo-ksuz8?file=/index.js
form.getVieldValue๋ฅผ Form.Item ๊ตฌ์ฑ ์์๋ก ์ด๋ํด์ผ ํฉ๋๋ค.
<Form.Item
shouldUpdate={(prevValues, curValues) =>
prevValues.username !== curValues.username
}
noStyle
>
{() => <div>{form.getFieldValue("username")}</div>}
</Form.Item>
๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ useRef()๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
Draw + Form. Modal + Form์ ๊ฒฝ์ฐ ๋ฐฉ๋ฒ์ด ์ ์ฉ๋ฉ๋๋ค.
const MyComp = React.memo(() => {
const [form] = Form.useForm();
const { getFieldValue } = form;
const category = getFieldValue('category'); // It's the culprit
return (/* something */);
})
์ ์ ํ ์ฌ์ฉ: ์์ ๋ฐฉ๋ฒ
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
>
{({ getFieldValue }) => {
return getFieldValue('gender') === 'other' ? (
<Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
<Input />
</Form.Item>
) : null;
}}
</Form.Item>
const MyComp = React.memo(() => {
const [form] = Form.useForm();
const { getFieldValue } = form;
const category = getFieldValue('category'); // It's the culprit
return (/* something */);
})
์ฌ๋ฐ๋ฅธ ์ฌ์ฉ ๋ฐฉ๋ฒ :
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
>
{({ getFieldValue }) => {
return getFieldValue('gender') === 'other' ? (
<Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
<Input />
</Form.Item>
) : null;
}}
</Form.Item>
ํผ ์์๊ฐ ๋ ๋๋ง๋์ง ์์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ์ง๋ง ํผ์ ๊ฐ์ ์ค์ ํ์ต๋๋ค. ์ด๊ฒ์ ๋ฐ์ ๋ฐ ํํฌ์ ๋ํ ๊ธฐ๋ณธ ์ง์์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ ๋๋ง๋ ์์์ ๊ธฐ๋ค๋ฆฌ๋ ๋ฐ setTimeout์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์์์ ์ด๊ธฐ ๊ฐ์ ์ค์ ํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์
<Form
initialValues={{
name: 'Hafid',
age: '35'
}}
onFinish={onFinish}
>
๋๋ ์ด ๋ฐฉ๋ฒ์ผ๋ก
```js
const [๊ฐ, setValues] = React.useState({})
React.useEffect(()=>{
// ์น ์๋น์ค ๋๋ API์์ ๋ฐ์ดํฐ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
// ๊ฒฐํจ(...)
if (values_from_api){
setValues(values_from_api);
}
}, [])
๋ฐํ <>
๋ด ์ฌ์ฉ์ ์ ์ ํํฌ์์ ์์ ๊ฐ์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํฉ๋๊น?
Ant 3์์๋ ๋ค์๊ณผ ๊ฐ์ด ํ์ต๋๋ค.
const [updating, updateInfo] = useMyOwnCustomHookForSubmitAction(getFieldsValue());
const submitForm = () => {
validateFields((err) => {
if (!err) updateInfo();
});
};
<Form>...</Form>
Ant 4์์ ๊ทธ๋ ๊ฒ ํ๋ ค๊ณ ํ๋ฉด ์ฃผ์ ์์ ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
const [form] = useForm();
const [updating, updateInfo] = useMyOwnCustomHookForSubmitAction(getFieldsValue());
const submitForm = () => {
validateFields((err) => {
if (!err) updateInfo();
});
};
<Form form={form}>...</Form>
์์์ ๋ชจ๋ฌ, forceRender=true, destroyOnClose=false ์ค์ ์ ๋๋ค. ๋ด๊ฐ ๋ฌด์์ ์๋ชปํ๊ณ ์์ง?
V4 ๋ฒ์ ์ฌ์ฉ์(ํจ์ ์ปดํฌ๋ํธ์ ํํ๊ฐ ์กด์ฌํจ) ์ด ๋ฌธ์ ๋ก ์ดํ๋์ ๊ณ ๋ฏผํ๋ค๊ฐ ๊ฑฐ์ ๋ค์ด๋ ๋ป ํ์ต๋๋ค.(์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ์ฌ์ฉ์๋ ์ง์ฅ์ด ์์์ต๋๋ค.) ๋ง์ง๋ง์ผ๋ก https://ant ๋ฅผ ์ฝ๊ฒ ๋์์ต๋๋ค
useEffect(() => {
๋ฐํ() => {
form.resetFields();
};
})
๋ฐํ()=>{....}์์ ์๋ฉธ์ ์ ๋ฐํ๋ ๊ฒ์ ์ ์ฒด ํจ์ ๊ตฌ์ฑ ์์์ ๋๋ค(ํ์ฌ ์์์ด ์๋ฉธ๋๋์ง ์ฌ๋ถ๋ ํ ์คํธ๋์ง ์์).
๋ฌธ์ ์ค๋ช : destroyOnClose | ๋ซ์ ๋ ๋ชจ๋ฌ์ ์์ ์์๋ฅผ ํ๊ดดํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค. forceRender | Modal์ ํ์ ๋ ๋๋ง, ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
์๋ฃจ์ : Modal์ forceRender=true, destroyOnClose=false, Modal์ด ์๋ฉธ(๋ซํ)๋๋ฉด ์ค๋ฅ๊ฐ ๋ณด๊ณ ๋์ง ์์ต๋๋ค. ์์์ ๋ด๋ถ ์ฝ๋๊ฐ ์คํ๋ ๋ ์ฐพ์ ์ ์์ง๋ง ์ ๋ ฅ ์ ์ด ID ๋ฐ๋ณต ๊ฒฝ๊ณ ๊ฐ ๋ณด๊ณ ๋ฉ๋๋ค(์ค๋ฅ๋ณด๋ค ์ฐ์ํจ).
๋๋ ๋ํ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ์ด ๋ฐฉ๋ฒ์ผ๋ก ํด๊ฒฐํ์ต๋๋ค.
๋ชจ๋ฌ ๊ตฌ์ฑ forceRender | ๊ฐ์ ๋ ๋๋ง
Modla ํ์์์ name={['modal','cityCode']}
Name={['search','cityCode']} ๋๋ name='cityCode' ํํฐ ์์
์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋ชจ๋ ๊ฒฝ๊ณ ๋ฅผ ํด๊ฒฐํ ์ ์์ผ๋ฉฐ ๊ณ ์ ํ์ง ์์ ID ๊ฒฝ๊ณ ๊ฐ ์๋ Found 2 ์์๋ ๋ณด๊ณ ๋์ง ์์ต๋๋ค โ
useRef๋ฅผ ์ฌ์ฉํ์ฌ ์์์ ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ๊ณ formRef.current์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
const formRef = useRef()
return (<Form ref={formRef}>
{
(formRef.current && formRef.current.getFieldsValue('key') === 1)
&&
(<Input />)
}
</Form>)
Modal์ Form์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๋๋ง๋์ง ์์ต๋๋ค. @se7en00๋ ์ ๋ต๊ธ์ ์ฐธ๊ณ ํ์ฌ Modal์
forceRender
๋ฅผ ์ถ๊ฐ ํ์๋ฉด ๋ฉ๋๋ค. ๋๋ Modal์ด ํ์๋๊ณ ๋ ๋๋ง์ด ์๋ฃ๋ ํsetFieldsValue
๋ฐresetFields
ํธ์ถํฉ๋๋ค.
๋ชจ๋ฌ์ forceRender ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ํ ์ธ๋ชจ๊ฐ ์์ต๋๋ค.
๊ณต์ ๋ธ๋ก์ ์๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฒฝ๊ณ ํฉ๋๋ค.
V4 ๋ฒ์ ์ฌ์ฉ์(ํจ์ ์ปดํฌ๋ํธ์ ํํ๊ฐ ์กด์ฌํจ) ์ด ๋ฌธ์ ๋ก ์ดํ๋์ ๊ณ ๋ฏผํ๋ค๊ฐ ๊ฑฐ์ ๋ค์ด๋ ๋ป ํ์ต๋๋ค.(์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ์ฌ์ฉ์๋ ์ง์ฅ์ด ์์์ต๋๋ค.) ๋ง์ง๋ง์ผ๋ก https://ant ๋ฅผ ์ฝ๊ฒ ๋์์ต๋๋ค
useEffect(() => {
๋ฐํ() => {
form.resetFields();
};
})
๋ฐํ()=>{....}์์ ์๋ฉธ์ ์ ๋ฐํ๋ ๊ฒ์ ์ ์ฒด ํจ์ ๊ตฌ์ฑ ์์์ ๋๋ค(ํ์ฌ ์์์ด ์๋ฉธ๋๋์ง ์ฌ๋ถ๋ ํ ์คํธ๋์ง ์์).
๋ฌธ์ ์ค๋ช : destroyOnClose | ๋ซ์ ๋ ๋ชจ๋ฌ์ ์์ ์์๋ฅผ ํ๊ดดํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค. forceRender | Modal์ ํ์ ๋ ๋๋ง, ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
์๋ฃจ์ : Modal์ forceRender=true, destroyOnClose=false, Modal์ด ์๋ฉธ(๋ซํ)๋๋ฉด ์ค๋ฅ๊ฐ ๋ณด๊ณ ๋์ง ์์ต๋๋ค. ์์์ ๋ด๋ถ ์ฝ๋๊ฐ ์คํ๋ ๋ ์ฐพ์ ์ ์์ง๋ง ์ ๋ ฅ ์ ์ด ID ๋ฐ๋ณต ๊ฒฝ๊ณ ๊ฐ ๋ณด๊ณ ๋ฉ๋๋ค(์ค๋ฅ๋ณด๋ค ์ฐ์ํจ).
์ด ๋ฐฉ๋ฒ์ ํด๊ฒฐํ ์ ์์ง๋ง ์ผํญ ์ฐ์ฐ์๊ฐ ํ์๋๋ ๊ฒฝ์ฐ Modal ๋ฐ forceRender=true์ ์ธ๋ถ ๊ณ์ธต์ ๊ฒฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ destroyOnClose=false๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
{visible ? : <Modal visible={visible} forceRender destroyOnClose={false}><Form form={form} onFinish={handleFinish}>...</Form></Modal> : null}
๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ง์คํฌ๋ง ํ์๋๊ณ ๊ธ๋จธ๋ฆฌ ๊ธฐํธ ์์๊ฐ ํ์๋์ง ์์ต๋๋ค.
์ด์ ๊ฐ์ด forceRender=true, destroyOnClose=false๋ก ์ค์ ํ๊ณ , onOk ๋๋ onCancel ํ์
์ด ๋ซํ ๋ form.resetFields()๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ์ด์ ์ค๋ฅ๊ฐ ๋ณด๊ณ ๋์ง ์์ต๋๋ค.
<Modal
visible={visible}
forceRender
destroyOnClose={false}
>
<Form form={form} onFinish={handleFinish}>...</Form>
</Modal>
๊ทธ๋ฌ๋ ์ผํญ ์ฐ์ฐ์ visible?์ ์ฌ์ฉํ์ฌ Modal์ ์ธ๋ถ ๋ ์ด์ด๋ฅผ ๊ฒฐ์ ํ๊ณ forceRender=true๋ก ์ค์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด destroyOnClose=false๊ฐ ๋ฉ๋๋ค.
{visible
? <Modal
visible={visible}
forceRender
destroyOnClose={false}
>
<Form form={form} onFinish={handleFinish}>...</Form>
</Modal>
: null
}
๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ง์คํฌ๋ง ํ์๋๊ณ ๊ธ๋จธ๋ฆฌ ๊ธฐํธ ์์๊ฐ ํ์๋์ง ์์ต๋๋ค.
๊ณต์ ์๋ฃจ์
๋งํฌ
V4 ๋ฒ์ ์ฌ์ฉ์(ํจ์ ์ปดํฌ๋ํธ์ ํํ๊ฐ ์กด์ฌํจ) ์ด ๋ฌธ์ ๋ก ์ดํ๋์ ๊ณ ๋ฏผํ๋ค๊ฐ ๊ฑฐ์ ๋ค์ด๋ ๋ป ํ์ต๋๋ค.(์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ์ฌ์ฉ์๋ ์ง์ฅ์ด ์์์ต๋๋ค.) ๋ง์ง๋ง์ผ๋ก https://ant ๋ฅผ ์ฝ๊ฒ ๋์์ต๋๋ค
useEffect(() => {
๋ฐํ() => {
form.resetFields();
};
})
๋ฐํ()=>{....}์์ ์๋ฉธ์ ์ ๋ฐํ๋ ๊ฒ์ ์ ์ฒด ํจ์ ๊ตฌ์ฑ ์์์ ๋๋ค(ํ์ฌ ์์์ด ์๋ฉธ๋๋์ง ์ฌ๋ถ๋ ํ ์คํธ๋์ง ์์).
๋ฌธ์ ์ค๋ช : destroyOnClose | ๋ซ์ ๋ ๋ชจ๋ฌ์ ์์ ์์๋ฅผ ํ๊ดดํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค. forceRender | Modal์ ํ์ ๋ ๋๋ง, ๊ธฐ๋ณธ๊ฐ์ false์ ๋๋ค.
์๋ฃจ์ : Modal์ forceRender=true, destroyOnClose=false, Modal์ด ์๋ฉธ(๋ซํ)๋๋ฉด ์ค๋ฅ๊ฐ ๋ณด๊ณ ๋์ง ์์ต๋๋ค. ์์์ ๋ด๋ถ ์ฝ๋๊ฐ ์คํ๋ ๋ ์ฐพ์ ์ ์์ง๋ง ์ ๋ ฅ ์ ์ด ID ๋ฐ๋ณต ๊ฒฝ๊ณ ๊ฐ ๋ณด๊ณ ๋ฉ๋๋ค(์ค๋ฅ๋ณด๋ค ์ฐ์ํจ).๋๋ ๋ํ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ์ด ๋ฐฉ๋ฒ์ผ๋ก ํด๊ฒฐํ์ต๋๋ค.
๋ชจ๋ฌ ๊ตฌ์ฑ forceRender | ๊ฐ์ ๋ ๋๋ง
Modla ํ์์์ name={['modal','cityCode']}
Name={['search','cityCode']} ๋๋ name='cityCode' ํํฐ ์์
์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋ชจ๋ ๊ฒฝ๊ณ ๋ฅผ ํด๊ฒฐํ ์ ์์ผ๋ฉฐ ๊ณ ์ ํ์ง ์์ ID ๊ฒฝ๊ณ ๊ฐ ์๋ Found 2 ์์๋ ๋ณด๊ณ ๋์ง ์์ต๋๋ค โ
[์์ ์ด๋ฆ์ ์์ ํ๋ ID์ ์ ๋์ฌ๋ก ์ฌ์ฉ๋ฉ๋๋ค.] ๋ฐ๋ผ์ ๊ณ ์ ํ์ง ์์ ID๋ฅผ ๊ฐ์ง Found 2 elements์ ๋ํ ๊ฒฝ๊ณ ๊ฐ ์์ต๋๋ค.
getContainer={false}๋ฅผ ๋ชจ๋ฌ ์์ฑ์ผ๋ก + form.resetFields()๋ฅผ ํธ์ถํ ๋ ๋ชจ๋ฌ์ ํ์ํ๋ฉด ๊ฒฝ๊ณ ๊ฐ ํ์๋์ง ์์ต๋๋ค.
useEffect(() => {
if (form && visible) {
form.resetFields();
}
}, [visible]);
์ด๋ฐ ์์ผ๋ก destroyOnClose๋ true๊ฐ ๋ ์ ์์ต๋๋ค.
Form.useFrom ๋์ useRef๋ฅผ ์ฌ์ฉํ์ฌ Form ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
const [visible, setVisible] = useState(false)
let form = useRef(null)
const closeModal = () => {
setVisible(false)
form.resetFields()
}
return (
<Modal
title="test"
visible={visible}
onCancel={closeModal}
footer={null}
>
<Form
name="test"
layout="vertical"
onFinish={onFinish}
ref={instance => { form = instance }}
>
<Form.Item
label="item"
name="item"
>
<Input />
</Form.Item>
<Form.Item
style={{
textAlign: 'right',
}}
>
<Space size="middle">
<Button type="primary" htmlType="submit">
submit
</Button>
<Button onClick={closeModal}>
cancle
</Button>
</Space>
</Form.Item>
</Form>
</Modal>
)
๋ด ๋ ์ผํธ๋ง :์ด ์ค๋ฅ๋ ๋ง์ดํธ๋์ง ์์ ์์์ ์ฌ์ค์ ํ๋ ค๊ณ ํ ๋ ํ์๋์์ผ๋ฏ๋ก ํ์ ์์์ ์ข ์์ฑ์ ์ถ๊ฐํ๋ฉด ํด๊ฒฐ๋์์ต๋๋ค.
useEffect(() => {
if (data) { // data is used to populate initialValues
form.resetFields();
}
}, [form, data])
ํธ์ง : @fabripeco๊ฐ ๋งํ ๊ฒ๊ณผ
๋๋ Popover์์ ์์์ ์ฌ์ฉํฉ๋๋ค. useRef
๋ ์ ์๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ๋ชจ๋ฌ์ ์ฌ์ฉํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
const formRef = useRef(null);
<Popover
content={renderEdit()}
visible={isEdit}
onVisibleChange={onToggleEdit}
>
<span onClick={onToggleEdit}>
{name}
</span>
</Popover>
function renderEdit() {
return (
<Form
initialValues={{ newName: name }}
form={form}
ref={formRef}
>
</Form>
);
}
function onToggleEdit() {
if (isEdit) {
toggleEdit(false);
} else if (!isEdit) {
if (formRef.current) {
form.setFieldsValue({
newName: name
});
}
toggleEdit(true);
}
}
๋ด ํด๊ฒฐ ๋ฐฉ๋ฒ์
Form
๊ฐ ๋ ๋๋ง๋ ๋useState
๋กref
์ ๋ง๋ ๋ค์ ์์ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ref
๋ฅผ ํ์ธํฉ๋๋ค.interface FormModalProps { data?: RoleProps; visible: boolean; onCancel?: () => void; onSubmit?: (values: Store) => void; submitting: boolean; } const FormModal: React.FC<FormModalProps> = props => { const [form] = Form.useForm(); const [formRef, setFormRef] = useState(); // <---- set the ref when Form Rendered const { data, onSubmit, onCancel, visible, submitting } = props; // reset Form when modal close useEffect(() => { if ( !props.visible && formRef) { // <---- check ref before use the form instance form.resetFields(); } }, [props.visible]); // fill Form when modal open useEffect(() => { if (visible && formRef) { // <---- check ref before use the form instance form.setFieldsValue({ ...data, }); } }, [props.data]); // handle form onFinish const handleFormFinish = (values: Store) => { if (onSubmit) { onSubmit(values); } }; // handle modal ok const handleOk = () => { if (!form) return; form.submit(); }; return ( <Modal title="Modal" confirmLoading={submitting} onOk={handleOk} onCancel={onCancel} visible={visible} width={640} > <Form ref={setFormRef} form={form} onFinish={handleFormFinish}> <Form.Item name="title" label="Title" > <Input /> </Form.Item> </Form> </Modal> ); };
๋ ์ด์ ๊ฒฝ๊ณ ๋ ์์ต๋๋ค!
์๋ฒฝํ๊ฒ ํด๊ฒฐ!
์ด ๊ฒฝ๊ณ ์ ๋ ๊ฐ์ง ์ด์ :
1.
๋๋ ์ด๊ฒ์ ์ฌ์ฉํ์ฌ ํด๊ฒฐํฉ๋๋ค.
<Modal
getContainer={false}
// destroyOnClose
>
๊ณต์ ์๋ฃจ์
๋งํฌ
์๋ฒฝ, ๋ชจ๋ฌ์ forceRender ์ถ๊ฐ
formHooked
์ ๊ณต๊ฐํ๊ณ ์ฌ์ฉ์๊ฐ ์ค์ค๋ก ํ๋จํ๊ฒ ํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๋ ํ์๋ค.์๋ก์์ getContainer={false}๋ฅผ ์ฌ์ฉํ๋ฉด ํด๊ฒฐํ ์ ์๋ค.๋ชจ๋ฌ๋ ๋ง์ฐฌ๊ฐ์ง๋ผ๊ณ ์๊ฐํ๋ค.
๋๋ ์๋์์ getContainer={false}๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ชจ๋ฌ์๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ์์ด์ผ ํฉ๋๋ค. ์๋ํด ๋ณผ ์ ์์ต๋๋ค.