Small form
Formik is our go-to for working with forms that contain multiple inputs and often includes validation and calling a service to mutate the state on submission.
export interface IPaymentMethod { Name: string; Code: string;}
export const PaymentMethodForm = () => { const intl = useIntl();
// Initial form values when loading the form const initialValues: IPaymentMethod = useMemo(() => ({ Name: '', Code: '' }), []);
// Callback to save the form values in the backend and a loading state which indicates that a save is in progress const { savePaymentMethod, isSaveLoading } = useAddPaymentMethod();
return ( <Card> <Box> <Formik initialValues={initialValues} onSubmit={(formValues, formikHelpers) => { savePaymentMethod(formValues); formikHelpers.setSubmitting(false); }} > {({ submitForm, isSubmitting }) => ( <> <Box p={0} mb="8px"> <Field name="Name"> {({ meta, field }: FieldProps) => ( <Input required label={intl.formatMessage({ id: 'payment-method.label.name', })} {...field} value={field.value ?? ''} error={meta.touched && !!meta.error} helperText={meta.touched && !!meta.error ? meta.error : undefined} /> )} </Field> </Box> <Box p={0}> <Field name="Code"> {({ meta, field }: FieldProps) => ( <Input required label={intl.formatMessage({ id: 'payment-method.label.code', })} {...field} value={field.value ?? ''} error={meta.touched && !!meta.error} helperText={meta.touched && !!meta.error ? meta.error : undefined} /> )} </Field> </Box> <Box> <Grid container justify="flex-end"> <Grid item> <Button variant="contained" color="primary" isLoading={isSubmitting || isSaveLoading} disabled={isSubmitting || isSaveLoading} onClick={submitForm} > <FormattedMessage id="button.label.save" /> </Button> </Grid> </Grid> </Box> </> )} </Formik> </Box> </Card> );};