How to use Formik with input names that have dots "."? - reactjs

I'm unable to get handleChange to update an input with dots "." in the name. Has anyone solved this?
<Formik component={({
handleSubmit,
handleChange,
handleBlur,
values,
errors,
}) => (
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={values['name.of.input']}
name="name.of.input"
/>
{errors['name.of.input'] && <div>{errors['name.of.input']}</div>}
<button type="submit">Submit</button>
</form>
)} />;
Edit: Here is the refactored version that works
<Formik component={({
initialValues={{
name: {
of: {
input: ''
}
}
}},
handleSubmit,
handleChange,
handleBlur,
values,
errors,
}) => (
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={values.name.of.input}
name="name.of.input"
/>
{getIn(errors, 'name.of.input') && <div>getIn(errors, 'name.of.input')</div>}
<button type="submit">Submit</button>
</form>
)} />;

You should use getIn and you can see an examples in the docs here and here.
const inputValue = getIn(values, 'name.of.input')
const inputError = getIn(errors, 'name.of.input')
const inputTouched = getIn(touched, 'name.of.input')

name.of.input means your Formik state should have shape something like this:
{
name: {
of: {
input: ''
}
}
}
Now the values you're getting from Formik will also have the same shape, so to access value off of values you need do this:
values={values.name.of.input}

Related

TypeError: Cannot read property 'setFieldValue' of undefined. Formik doesn't recognise setFieldValue

I'm trying to create an image upload on my form. The problem is when I try to change the value to the actual uploaded file. I am trying to use setFieldValue, but it says it is undefined. Below is the code. Any ideas why it is undefined? I thought it comes with Formik.
import { Formik } from 'formik';
const AddProduct = (props) => {
return (
<Formik
initialValues={{
serviceImage: null
}}
onSubmit={(values) => {
console.log(values);
}}
>
{({
errors,
handleBlur,
handleChange,
handleSubmit,
setFieldValue,
isSubmitting,
touched,
values,
formProps
}) => (
<form onSubmit={handleSubmit}>
<TextField
error={Boolean(touched.serviceName && errors.serviceName)}
fullWidth
helperText={touched.serviceName && errors.serviceName}
label="Service name"
margin="normal"
name="serviceName"
onBlur={handleBlur}
onChange={handleChange}
value={values.serviceName}
/>
<Button>
<input
id="file"
name="serviceImage"
value={values.serviceImage}
type="file"
onChange={(event) => formProps.setFieldValue('serviceImage', event.target)
}
/>
Add an Image
</Button>
<Button
type="submit" >
Post this service on the Events Platform
</Button>
</form>
)}
</Formik>
);
};
You already declare setFieldValue in your formik callback function
So change it to:
<input
id="file"
name="serviceImage"
value={values.serviceImage}
type="file"
onChange={event => setFieldValue('serviceImage', event.currentTarget.files[0])}
/>;

Formik form not rendering

Just setting up a basic bonehead form for learning purposes and ... can't seem to render. No errors. Functional component runs. Just nothing to see...
MyForm.tsx
export const MyForm: React.FC = () => {
console.log("MyForm has been called")
return (
<div>
<Formik initialValues={{ firstName: "roberto" }} onSubmit={data => { console.log(data) }}>
{({ values, handleChange, handleSubmit, handleBlur }) => {
<form onSubmit={handleSubmit}>
<TextField value={values.firstName} onChange={handleChange} onBlur={handleBlur} name="firstName" />
<pre>JSON.stringify(values)</pre>
</form>
}}
</Formik>
</div >
)
}
I've imported MyForm properly into App.tsx, and MyForm is currently all I'm returning from App.tsx.
No errors. Just nothin...
I don't think you're returning your form which is why it's not rendering:
export const MyForm: React.FC = () => {
console.log("MyForm has been called")
return (
<div>
<Formik initialValues={{ firstName: "roberto" }} onSubmit={data => { console.log(data) }}>
{({ values, handleChange, handleSubmit, handleBlur }) => (
<form onSubmit={handleSubmit}>
<TextField value={values.firstName} onChange={handleChange} onBlur={handleBlur} name="firstName" />
<pre>JSON.stringify(values)</pre>
</form>
)}
</Formik>
</div >
)
}
Note that I changed the function's curly braces to parens around your <form>. Alternatively, you could leave the curly braces and instead
{({ values, handleChange, handleSubmit, handleBlur }) => {
return (<form>...</form>)
}}

React Bootstrap Form.Check with Formik

How can I properly bind Form.Check to a boolean variable using yup and Formik?
React-Bootstrap 4.5 provides an example of using Formik + yup with form inputs. I was able to setup text inputs and selects, but encountered a problem with Form.Check element. I expect it to provide simple boolean value on change, but instead I'm getting an empty array [] or ["on"] when checkbox is checked.
The documentation also has this issue, in the example from the link above form displays this error message:
terms must be a boolean type, but the final value was: ["on"].
My code:
const schema = yup.object({
deactivated: yup.boolean(),
});
const initialValues = {
deactivated: false,
};
return (
<Formik
validationSchema={schema}
onSubmit={(
values
) => {
save(
values.deactivated,
);
}}
initialValues={initialValues}>
{({
handleSubmit,
handleChange,
values,
errors,
}) => (
<Form noValidate onSubmit={handleSubmit}>
<Form.Group controlId="deactivated">
<Form.Check
label="Deactivated"
type="checkbox"
value={values.deactivated}
onChange={handleChange}
isInvalid={!!errors.deactivated}
/>
</Form.Group>
<Button type="submit">Save</Button>
</Form>
)}
</Formik>
);
I was able to handle checkbox changes manually using setFieldValue method:
extract setFieldValue method from Formik
bind checkbox to checked property instead of value
use custom onChange handler: {e => setFieldValue('deactivated', e.target.checked)}
Code:
return (
<Formik
validationSchema={schema}
onSubmit={(
values
) => {
save(
values.deactivated,
);
}}
initialValues={initialValues}>
{({
handleSubmit,
handleChange,
values,
errors,
setFieldValue,
}) => (
<Form noValidate onSubmit={handleSubmit}>
<Form.Group controlId="deactivated">
<Form.Check
label="Deactivated"
type="checkbox"
checked={values.deactivated}
onChange={e => setFieldValue('deactivated', e.target.checked)}
isInvalid={!!errors.deactivated}
/>
</Form.Group>
<<Button type="submit">Save</Button>
</Form>
)}
</Formik>
);

onchange in a form using formik the value of the field is not updated

I'm new to react, and I'm trying to apply validations to a form.
For some reason when adding the property:
onChange={onChange}
I want to send the values to the parent component. That's why I'm using the onchange.
Nothing I write is shown in my text fields, why does this happen?
export const Son = props => {
const { onChange } = props;
return (
<Formik
initialValues={{
fullname: "",
email: ""
}}
validationSchema={Yup.object().shape({
fullname: Yup.string()
.min(2, "Your name is too short")
.required("Please enter your full name"),
email: Yup.string()
.email("The email is incorrect")
.required("Please enter your email")
})}
onSubmit={(values, { setSubmitting }) => {
const timeOut = setTimeout(() => {
console.log(values);
setSubmitting(false);
clearTimeout(timeOut);
}, 1000);
}}
>
{({
values,
errors,
touched,
handleSubmit,
isSubmitting,
validating,
valid
}) => {
return (
<Form name="contact" method="post" onSubmit={handleSubmit}>
<label htmlFor="fullname">
Fullname
<Field
type="text"
name="fullname"
autoComplete="name"
placeholder="your fullname"
onChange={onChange}
/>
</label>
{<ErrorMessage name="fullname">{msg => <p>{msg}</p>}</ErrorMessage>}
{/*errors.fullname && touched.fullname && <p>{errors.fullname}</p>*/}
<br />
<label htmlFor="email">
Email
<Field
type="email"
name="email"
autoComplete="email"
placeholder="your email"
onChange={onChange}
/>
</label>
<ErrorMessage name="email">{msg => <p>{msg}</p>}</ErrorMessage>
<br />
<button type="submit" disabled={!valid || isSubmitting}>
{isSubmitting ? `Submiting...` : `Submit`}
</button>
</Form>
);
}}
</Formik>
);
};
this is my live code:
https://stackblitz.com/edit/react-qotvwb?file=components/son_component.js
you're not using the formik handleChange at all.
I highlighted the changes that I made in https://stackblitz.com/
and you can test this working here

understanding Formik and React

This is probably not the best place to post this question but where, then?
The code below is taken from Formik's overview page and I'm very confused about the onSubmit handlers:
The form element has an onSubmit property that refers to handleSubmit which is passed on that anonymous function : <form onSubmit={handleSubmit}>. Where does that come from?
The Formik component has an onSubmit property as well:
onSubmit={(values, { setSubmitting }) => { ... }
How do these relate to each other? What is going on?
import React from 'react';
import { Formik } from 'formik';
const Basic = () => (
<div>
<h1>Anywhere in your app!</h1>
<Formik
initialValues={{ email: '', password: '' }}
validate={values => {
let errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (
!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
/* and other goodies */
}) => (
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
onChange={handleChange}
onBlur={handleBlur}
value={values.email}
/>
{errors.email && touched.email && errors.email}
<input
type="password"
name="password"
onChange={handleChange}
onBlur={handleBlur}
value={values.password}
/>
{errors.password && touched.password && errors.password}
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</form>
)}
</Formik>
</div>
);
export default Basic;
The component takes onSubmit as a prop where you can execute code you want to perform when you submit your form. This prop is also given some arguments such as values (values of the form) for you to use in your onSubmit function.
The handleSubmit form is auto generated from the Formik library that automates some common form logics explained here. The handleSubmit will automatically execute onSubmit function mentioned above as part of its phases (pre-submit, validation, submission). Hope that answers your question!

Resources