I have this modal and I have a formik object created. All the inputs are getting rerendered every change I type
Formik object
const formik = useFormik({
enableReinitialize: true,
initialValues: {
sp_id: data?.id,
websites: data?.websites || [],
create_websites: [],
delete_websites: [],
update_websites: []
},
validationSchema: Yup.object({
sp_id: Yup.string().required("This field is required and can\'t not be changed"),
websites:Yup.array().of(Yup. string())
}),
onSubmit: (values) => {
console.log('submit:',values)
}
});
Form Input
const FormInput = ({ name, value, placeholder, ...rest }) => (
<div className="space-y-1 w-full pt-3 pr-2">
<label className="font-bold text-sm text-secondary">
Web Link
<span className="text-red-500">*</span>
</label>
<Input
{...formik.getFieldProps(name)}
value={value}
placeholder={placeholder}
onChange={(e) => {
formik.handleChange(e);
formik.setFieldValue(name, e.target.value);
}}
{...rest}
/>
</div>
);
and I am using ant design
<Form.List name="websites">
{(fields, {add, remove}) => {
return (
(
<div key="test">
{
fields.map(({name, key, isListField, fieldKey, ...restField}) => {
return (
<div key={fieldKey}>
<Form.Item
{...restField}
name={[name, 'domain']}
fieldKey={[fieldKey, 'domain']}
validateTrigger={["onChange", "onBlur"]}
rules={[
{
required: true,
message: 'Domain is required'
}
]}
noStyle
className="w-full"
>
<div className="flex items-end w-full">
<FormInput
name={`websites.${key}.domain`}
placeholder="URL"
value={formik.values.websites[key]?.domain}
/>
{fields.length > 1 && (
<Button
type="default"
size="small"
icon={<LuTrash2 size={20}/>}
onClick={() => {
if (formik.values.websites[key]) {
formik.setFieldValue(
'delete_websites',
[
...formik.values.delete_websites,
formik.values.websites[key]
]
);
remove(name)
}
}}
className="mb-1 bg-[#F06548] border-[#F06548] text-white flex items-center justify-center h-full"
/>
)}
</div>
</Form.Item>
</div>
);
}
)}
<div className="mt-5 w-full">
<AntButton
type="dashed"
onClick={() => {
add();
}}
icon={<PlusOutlined />}
className="w-full border-2 border-dashed border-gray-500"
>
Add Website
</AntButton>
</div>
</div>
)
);
}}
</Form.List>
The problem is that on every change I make it the input is getting unfocused / re-rendered
Im Trying to handle on change smoothly and not to cause any re-render
So Instead of pursuing using Ant Design's Form List I used Formik's, Formik component, Form, FieldArray, and Field.
const Index = ({data, isOpen, setIsOpen, mutate}) => {
const validationSchema = Yup.object({});
const initialValues = {};
const handleSubmit = async (values, resetForm) => {};
const handleAdd = (values, values) => {};
const handleChange = (form, name, value) => {};
return (
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
enableReinitialize={true}
>
{(formikProps) => (
<Modal {...actions}>
<Form onFinish={() => handleSubmit(formikProps.values, formikProps.resetForm)}>
{({ field, meta }) => (
<Input
{...field}
onChange={(e) => {
field.onChange(e);
handleChange(formikProps, field.name, e.target.value);
}}
/>
)}
</Form>
</Modal>
)}
</Formik>
);
}