I am trying to create an input field, if a place inside <Formik> should act as a Formik Field, but if no Formik is available, then it should act as a general input field. So far I have managed to this using useFormikContext and useField inside the High Order Component (HOC). But I am facing another issue, which actually lead me here, I want to return WrapperComponent with some data, like if field have errors, then I can receive where I am using WrapperComponent.
withField.tsx (HOC)
import { useField, useFormikContext } from "formik";
export const withField = (WrappedComponent: React.ComponentType) => {
const displayName =
WrappedComponent.displayName || WrappedComponent.name || "Component";
const ComponentWithOrWithoutFormik = (props: any) => {
const formikContext = useFormikContext();
if (formikContext) {
const [field, meta] = useField(props);
return (
<WrappedComponent
{...field}
{...props}
onChange={(e: any) => {
field.onChange(e);
props.onChange && props.onChange(e);
}}
onBlur={(e: any) => {
field.onBlur(e);
props.onBlur && props.onBlur(e);
}}
/>
);
}
return <WrappedComponent {...props} />;
};
ComponentWithOrWithoutFormik.displayName = `withOrWithoutFormik(${displayName})`;
return ComponentWithOrWithoutFormik;
};
In other file:
const CheckBoxField = withField((props) => <input {...props} />);
And currently I am using it like this:
<CheckBoxField id={`id_${name}`} type="checkbox" name={name} />
But what I actually want to do is use it like this:
<CheckBoxField id={`id_${name}`} type="checkbox" name={name}>
{({errors, touched})=>(
// something I can do here
)}
</CheckBoxField>
I can do this with simple component by simply returning children like this:
const SomeComponent = ({children, ...props}) => {
return children(props)
}
But have no idea, how to do it with HOC.
So after, many trials and errors, the answer was using RenderProps, and this is how I have done it:
};