Ant-design: 'useForm'์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋Š” ์–ด๋–ค Form ์š”์†Œ์—๋„ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 'form' prop์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ์žŠ์œผ์…จ์Šต๋‹ˆ๊นŒ? ๋ถ„๋ช…ํžˆ ์˜ˆ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2020๋…„ 02์›” 23์ผ  ยท  56์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: ant-design/ant-design

  • [] ์ด ์ €์žฅ์†Œ์˜ ๋ฌธ์ œ ๋ฅผ ๊ฒ€์ƒ‰ํ–ˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ์ค‘๋ณต๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์žฌ์ƒ์‚ฐ ๋งํฌ

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('๊ฒ€์ฆ ์‹คํŒจ:', ์ •๋ณด);
});
}}
>

์–‘์‹={์–‘์‹}
๋ ˆ์ด์•„์›ƒ = "์ˆ˜์ง"
์ด๋ฆ„="form_in_modal"
์ดˆ๊ธฐ๊ฐ’={{
์ˆ˜์ •์ž: '๊ณต๊ฐœ',
}}
>



์ด๋ฆ„ = "์ œ๋ชฉ"
label="์ œ๋ชฉ"
๊ทœ์น™={[
{
ํ•„์ˆ˜: ์‚ฌ์‹ค,
message:'์ปฌ๋ ‰์…˜์˜ ์ œ๋ชฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”!',
},
]}
>







);
};

์˜ˆ์ƒ๋˜๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด useForm์„ ์ •์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

index.js:1 ๊ฒฝ๊ณ : useForm ์˜ํ•ด ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋Š” Form ์š”์†Œ์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. form prop ์ „๋‹ฌ์„ ์žŠ์œผ์…จ์Šต๋‹ˆ๊นŒ?
CollectionCreateForm์—์„œ ....

const [์–‘์‹] = Form.useForm();
form.setFieldsValue({
์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„: caseDetail.categoryName,
});

์–‘์‹={์–‘์‹}
๋ ˆ์ด์•„์›ƒ = "์ˆ˜์ง"
์ด๋ฆ„="form_in_modal"
์ดˆ๊ธฐ๊ฐ’={{
์ˆ˜์ •์ž: '๊ณต๊ฐœ',
}}
>

| ํ™˜๊ฒฝ | ์ •๋ณด |
|---|---|
| ๊ฐœ๋ฏธ | 4.0.0-rc.5 |
| ๋ฐ˜์‘ | 16.8.6 |
|์‹œ์Šคํ…œ |mac10.15.3 |
| ๋ธŒ๋ผ์šฐ์ € | ํฌ๋กฌ |


๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์— ๋”ฐ๋ผ ์ง์ ‘ ์™”๋Š”๋ฐ ์ด ์˜ค๋ฅ˜๊ฐ€ ์—ฌ๊ธฐ์ €๊ธฐ์„œ ๋ณด๊ณ ๋˜์–ด ํ•  ๋ง์„ ์žƒ์—ˆ์Šต๋‹ˆ๋‹ค.

โ“FAQ

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ํ’€์—ˆ๋‹ค.์„œ๋กœ์—์„œ getContainer={false}๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.๋ชจ๋‹ฌ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.
๋‚˜๋Š” ์„œ๋ž์—์„œ getContainer={false}๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋‹ฌ์—๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  56 ๋Œ“๊ธ€

image

@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์˜ ๊ฒฝ์šฐ ๋ฐฉ๋ฒ•์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

  1. forceRender=true, destroyOnClose=false ๋‚ด ๊ตฌ์„ฑ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 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>

  1. forceRender=true, destroyOnClose=false ๋‚ด ๊ตฌ์„ฑ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„์˜ ์—ฐ๊ฒฐ๋กœ ์ธํ•ด ๋‚ด ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
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);
}
}, [])

๋ฐ˜ํ™˜ <>

์ดˆ๊ธฐ๊ฐ’={๊ฐ’}
onFinish={onFinish}
>

๋‚ด ์‚ฌ์šฉ์ž ์ •์˜ ํ›„ํฌ์—์„œ ์–‘์‹ ๊ฐ’์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ?
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 }
๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์Šคํฌ๋งŒ ํ‘œ์‹œ๋˜๊ณ  ๊ธ€๋จธ๋ฆฌ ๊ธฐํ˜ธ ์ƒ์ž๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ณต์‹ ์†”๋ฃจ์…˜
image
๋งํฌ

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.+
2."form.setFields()" ๋˜๋Š” useEffect()์˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜

๋‚˜๋Š” ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

<Modal
        getContainer={false}
        // destroyOnClose
>

๊ณต์‹ ์†”๋ฃจ์…˜
image
๋งํฌ

์™„๋ฒฝ, ๋ชจ๋‹ฌ์— forceRender ์ถ”๊ฐ€

formHooked ์„ ๊ณต๊ฐœํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์Šค์Šค๋กœ ํŒ๋‹จํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰