Reputation: 135
I created a custom input called <FormInput>
and applied useField()
and useFormikContext()
to it:
const [field, meta] = useField(props);
const { setFieldValue } = useFormikContext();
<FormInput>
is part of a library called UI
. I'm importing the library and trying to create a very simple form to test, a single field, the only validation being that it's required:
import React, { useContext } from "react";
import { DataContext } from "../../context/DataContext";
import * as UI from "@tui/uilibrary";
import { composeThemeFromProps } from "@css-modules-theme/react";
import styles from "./EnrollStep5.module.scss";
import { Formik, Form } from "formik";
import * as Yup from "yup";
const EnrollStep5 = (props) => {
const context = useContext(DataContext);
const theme = composeThemeFromProps(styles, [context, props]);
return (
<Formik
initialValues={{
name: "",
}}
validationSchema={Yup.object().shape({
name: Yup.string().required("Required"),
})}
>
{(props) => {
<Form className={theme.EnrollStep2}>
<UI.FormInput type={"text"} name={"name"} label={"Name"} />
</Form>;
}}
</Formik>
);
};
export default EnrollStep5;
This comes up blank. The Formik object appears in the Component browser, but shows as if it has no children. I have the feeling this is just due to inexperience and that I'm close. What am I doing wrong?
Upvotes: 0
Views: 886
Reputation: 59
You need to use <Field>
component inside of <Form>...</Form>
like this:
<Formik initialValues={{name: ""}}>
<Form>
<Field name="name" placeholder="Name:"></Field>
</Form>
</Formik>
<Field>
component will pass their value to formik and it can handle submit and etc.
You can create custom Field component:
<Formik initialValues={{ name: "" }}>
<Form>
<Field name="name" placeholder="Name:">
{({ field }) => (
<CustomInput {..field} />
)}
</Field>
</Form>
</Formik>
<CustomInput>
should include a html <input/>
element or you can use flowbite, materialUI input components like this.
If you want to pass error or touched objects to custom components you should try this solution:
<Formik initialValues={{ name: "" }}>
{({ values, errors, touched }) => (
<Form>
<Field name="name" placeholder="Name:">
{({ field }) => (
<CustomInput {...field} errors={errors} value={values}/>
)}
</Field>
</Form>
)}
</Formik>
Upvotes: 0
Reputation: 21
In short:
Wrap the <Form>...</Form>
in (parantheses) instead of {curly braces}.
Little more detailed:
So basically what is happening in your code with the curly braces is you are entering the callback function. So the <Form>...</Form>
is just floating around somewhere in the function body. What you intend to do is to return it.
So you can either add a return statement (return <Form>...</Form>;
) inside the curly braces or directly return the value without entering the function body. E.g. like (props) => <Form>...</Form>
or (props) => (<Form>...</Form>)
, whichever you prefer.
Upvotes: 2