Fields: leverage the React Context
See original GitHub issueIs your feature request related to a problem? Please describe.
ui-kit Fields
components use Formik.
We use Formik to handle our form state
However, this usage is not efficient as it involves a lot of props drilling. Let’s take TextField
as an example, you can see in the following code that all Formik related props are being repeated explicitly, onChange
-> formik.handleChange
, etc.
function MyComponent() {
const formik = useFormikContext();
<TextField
name="sku"
title="SKU"
value={formik.values.sku}
errors={formik.errors.sku}
touched={formik.touched.sku}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
/>;
}
This can be slightly improved by using getFieldProps
, but it’s still a chore to repeat each time a Field
component is used.
function MyComponent() {
const formik = useFormikContext();
<TextField
- name="sku"
title="SKU"
- value={formik.values.sku}
- errors={formik.errors.sku}
- touched={formik.touched.sku}
- onBlur={formik.handleBlur}
- onChange={formik.handleChange}
+ {...formik.getFieldProps('sku')}
/>;
}
Describe the solution you’d like
The solution is already provided by Formik, Leveraging the React Context. The idea is to update ui-kit Fields
components to benefit from this solution. This means updating TextField
to something similar to the following (copied from the mentioned Formik docs page above):
function TextField(props) {
// useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
// which we can spread on <input>. We can use field meta to show an error
// message if the field is invalid and it has been touched (i.e. visited)
const [field, meta] = useField(props);
return (
<>
<label htmlFor={props.id || props.name}>{label}</label>
<input className="text-input" {...field} {...props} />
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</>
);
};
This means that finally the usage of TextField
will be simplified to the following:
function MyComponent() {
- const formik = useFormikContext();
<TextField
name="sku"
title="SKU"
- {...formik.getFieldProps('sku')}
+ // any other non related Formik props
/>;
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (7 by maintainers)
@emmenko I see it makes sense. So what you’re suggesting is a nice solution without introducing trade-offs when introducing new wrapper components. This will avoid us diverging from using ui-kit components, and at the same time allow us to benefit from leveraging the React context using
useField
.In this case, I agree and would even consider your solution to be the right way to go. I already flagged the wrapped component that I created to not be used anymore and added a TODO to remove its usages.
Thanks again for your suggestion.
Ok thanks for clarifying this.
To be honest, I still don’t see a huge value in having such wrapper components and I believe we can go with
useField
approach first.