PrimeReact에서 Formik 으로 Form 개발하는 법 정리.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {useEffect, useState, useContext, useRef} from 'react'; | |
import { Dialog } from 'primereact/dialog'; | |
import { Button } from 'primereact/button'; | |
import { InputText } from 'primereact/inputtext'; | |
import { useFormik } from 'formik'; | |
import { classNames } from 'primereact/utils'; | |
export function FormDemo(props) { | |
const [editMode, setEditMode] = useState(true); // 한 Dialog를 공유하기 위해, true이면 편집모드, false이면 Add New Mode | |
const [showNew, setShowNew] = useState(false); | |
const [initialData, setInitialData] = useState({ | |
sid: null, | |
name: "", | |
address: "", | |
description: "", | |
owner: "" | |
}); | |
const formik = useFormik({ | |
initialValues: initialData, | |
enableReinitialize: true, | |
validate: (data) => { | |
let errors = {}; | |
if (!data.name) { | |
errors.name = "이름을 입력하세요"; | |
} | |
if (!data.address) { | |
errors.address = "주소를 입력하세요"; | |
} | |
return errors; | |
}, | |
onSubmit: (data) => { | |
console.log("formik onSubmit"); | |
console.dir(data); | |
/* Do the real thing here */ | |
/* | |
if (editMode === true) { | |
onUpdateSite(); | |
} else { | |
onCreateSite(); | |
} | |
*/ | |
} | |
}); | |
const isFormFieldInvalid = (name) => !!(formik.touched[name] && formik.errors[name]); // !! 는 truethy, falsey 값을 true, false로 정규화함. | |
const getFormErrorMessage = (name) => { | |
return isFormFieldInvalid(name) ? <small className="p-error">{formik.errors[name]}</small> : <small className="p-error"> </small>; | |
} | |
const renderDialogFooter = () => { | |
return ( | |
<div> | |
<Button label="Cancel" icon="pi pi-times" onClick={() => setShowNew(false)} className="p-button-text" /> | |
<Button label={editMode===true ? "수정하기" : "만들기"} icon="pi pi-check" onClick={formik.handleSubmit} type="button" autoFocus /> | |
</div> | |
); | |
} | |
return ( | |
<div> | |
<Dialog header={editMode ? `사이트 수정: ID=${sid}` : "새 사이트 등록"} visible={showNew} style={{ width: '500px' }} footer={renderDialogFooter} onHide={() => setShowNew(false)}> | |
<form onSubmit={formik.handleSubmit} onReset={formik.handleReset}> | |
<div className="grid mt-4"> | |
<div className="col-12"> | |
<span className="p-float-label"> | |
<InputText id="name" value={formik.values.name} onChange={(e) => formik.setFieldValue('name', e.target.value)} | |
className={classNames('width-100', {'p-invalid': isFormFieldInvalid('name')})} size={60}/> | |
<label htmlFor="name">사이트 이름</label> | |
</span> | |
{getFormErrorMessage('name')} | |
</div> | |
<div className="col-12"> | |
<span className="p-float-label"> | |
<InputText id="owner" value={formik.values.owner} onChange={(e) => formik.setFieldValue('owner', e.target.value)} | |
className={classNames("width-100", {"p-invalid": isFormFieldInvalid('owner')})} size={60}/> | |
<label htmlFor="owner">소유자 ID</label> | |
</span> | |
{getFormErrorMessage('owner')} | |
</div> | |
<div className="col-12"> | |
<span className="p-float-label"> | |
<InputText id="address" value={formik.values.address} onChange={(e) => formik.setFieldValue('address', e.target.value)} | |
className={classNames("width-100", {'p-invalid': isFormFieldInvalid('address')})} size={60}/> | |
<label htmlFor="address">사이트 주소</label> | |
</span> | |
{getFormErrorMessage('address')} | |
</div> | |
<div className="col-12"> | |
<span className="p-float-label"> | |
<InputText id="description" value={formik.values.description} onChange={(e) => formik.setFieldValue('description', e.target.value)} | |
className={classNames("width-100", {'p-invalid': isFormFieldInvalid('description')})} size={60}/> | |
<label htmlFor="description">사이트 설명</label> | |
</span> | |
{getFormErrorMessage('description')} | |
</div> | |
</div> | |
</form> | |
</Dialog> | |
</div> | |
); | |
} |