I have a formik field. I need to extract the value from this field and run it through a custom onChange function that changes state based on what the user types in. I'm not great with Formik at all. Some help would be highly apprecieted!
<Formik
initialValues={initialValues}
validationSchema={SetPasswordSchema}
onSubmit={onSubmit}
>
{({ status, isSubmitting, isValid, values }) => (
<Field
name='password'
required
value={values.password}
onChange={handleChange(values.password)}
component={TextField}
placeholder={t('authentication:password')}
type='password'
The formik field can not detect my handleChange function, and it is retruning as undefined. Any solution for this??
You can create a reference to Formik component.
this reference will have methods for doing various operations, from that you can use setFieldValue method to change a particular field.
check sandbox example
Related
I'm aware of FormSpy to update based on subscriptions to the form's changed input values.
I'm just not 100% sure on implementation for it. I also tried mutations but that didn't update the state values.
<Field name="city">
{({ input, meta }) => (
<label
>
City
</label>
<input
{...input}
type="text"
placeholder="123 Main Street"
id="city"
onChange={(e) => updatedLocationValues(e)}
value={location.city}
/>
)}
</Field>
This field is tied to state and is auto-populated by another field (users can still change it if they want through manual inputs)
The onChange is updating the state.
However React-final-form doesn't know about this state change. This is where FormSpy is supposed to come in but i'm not sure how to integrate it here.
I am on a dead end here with React Hook Form phone masking and validation. Any help will be greatly appreciated!
I am using React Hook Form and Yup for form and validation and MUI for UI. I was somehow able to add masking to my phone field using react-hook-form Controller component and react-input-mask for masking. But now I am not getting the Yup validation errors (helper text) that we get on form submit, on blur or on change.
I think it's because the masking already has hyphens which the field takes as value so it's technically never empty. But the problem is that when I add this field to the form, I don't get helper text to any of the other fields as well.
I have created a codesandbox for it. I want to make it a required field with minimum and maximum 15 characters (including + sign and two hyphens). I am not getting any helper text or error message and the form submits even if the user typed just one character.
Here's the Yup validation schema:
const Schema = Yup.object().shape({
cellPhone: Yup.string().min(15).max(15).required('Cell phone is required'),
});
const methods = useForm({
resolver: yupResolver(Schema),
defaultValues,
});
Here's the RHF form field:
<Controller
name="cellPhone"
control={control}
defaultValue=""
render={({ field: { onChange, value }, fieldState: { error } }) => (
<InputMask
mask="+99-999-9999999"
value={value}
onChange={onChange}
>
{(inputProps) => (
<TextField
error={!!error}
helperText={error?.message}
label="Cell phone"
variant="outlined"
type="text"
fullWidth
required
{...inputProps}
/>
)}
</InputMask>
)}
/>
Here's the codesandbox link:
https://codesandbox.io/s/magical-hooks-8zsgbb
If you have any solution, please let me know. Thanks!
I have been working on a form and been using Formik. For some reason all the props like errors and values are being passed but touched is not working. I am assuming that touched is not properly set up but I am unsure what would be causing it. I currently have this:
<Formik
initialValues={{date: ''}}
validation={{date: Yup.string().required('some error')}}
onSubmit={(values) => { console.log(values) }}
>
{({ errors, touched, values, setFieldValue }) => {
<form onSubmit={handleSubmit}>
...
<DatePicker
id="date"
name="date"
value={values.date}
errors={errors.date}
touched={touched.date}
onChange={setFieldValue}
/>
<button type='submit'>Submit</button>
</form>
}}
</Formik>
I have been checking the prop values being sent in and the only thing that is not working is touched as it is undefined. Did I configure the date picker incorrectly here? I am getting everything else and I am able to set the value but touched is never set. I have other fields similar to this as well but is working fine. What could be causing this issue?
I managed to fix this by passing the handleBlur handler to the DatePicker component
onBlur={handleBlur}
Can't seem to find a reason why the first approach works, and the second doesn't.
Works: pastebin
Doesn't: pastebin
The difference between these two is that there's <TextField> in the second one instead of <div> and <Field>. But the examples I've seen makes the <TextField> work just fine, what am I missing?
You have to pass the component to <Field />:
<Field component={TextField} name="password">
You are now trying to use it like so:
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
render={props => (
<Form>
<TextField
id="name"
name="name"
label="Name"
value={props.values.name}
onChange={props.handleChange}
fullWidth
/>
</Form>
)}
/>
... Which should work, are you getting any errors in the console?
If that doesn't work for some reason you can try doing it via Field render props.
This snippet is taken from the Formik docs.
<Formik
...
<Field
name="lastName"
render={({ field }) => (
<input {...field} placeholder="password" />
)}
/>
...
/>
You see you can use a render props to the Field component to render a custom component if you like.
There are 3 ways to render things with <Field>.
Aside from
string-only component, each render prop is passed the same props for
your convenience.
Field's render props are an object containing:
field: An object containing onChange, onBlur, name, and value of the
field form: Formik state and helpers Any other props passed to field
See more in Formik docs here.
Goal: Get the input values from a material UI component and pass them to an action creator in a handleSubmit function.
<Field name='email'
component={email =>
<TextField
fullWidth
autoComplete='off'
className={classes.textField}
id='email-text-field'
label='Email'
value={email} />
} />
<Field name='password'
component={password =>
<TextField
type='password'
fullWidth
autoComplete='off'
className={classes.textField}
id='password-text-field'
label='Password'
value={password} />
} />
This is how it is being connected to Redux:
#reduxForm({form: 'loginForm', fields: ['email', 'password']})
The warnings I'm getting in my chrome dev tools console is:
Failed prop type: Invalid prop value supplied to TextField.
Warning: Failed prop type: Invalid prop value supplied to Input.`
Additionally, the email field in my login form shows [Object, object}
My guess is that this is happening due to the fact that props are being passed from the
Any ideas on where I've gone wrong?
When you want to use a custom field for Redux-Form, Redux-form gives you access to both props like onChange etc, but also other meta-data (like if the form has been touched or not). These different kinds of props are grouped depending on type.
The interesting part for you is that all the attributes associated with a normal input element (like onChange, value, type) are grouped in props.input. So the argument you call password is actually the whole props object that is sent down to the component. It looks something like this {input:{ value: 'someValue', onChange: somFunction.. etc. etc}, meta: { touched: false, etc. etc.}}.
That means that if you want to use the TextField like you do now, you need to do something like:
<Field name='email'
component={({input}) =>
<TextField
value={input.value}
onChange={input.onChange}
fullWidth
autoComplete='off'
className={classes.textField}
id='email-text-field'
label='Email'
/>
} />
This can get pretty messy, especially if you want to use the meta props, so it's often worth it to break the custom component logic out into its own function, like they do in the example in the docs: https://redux-form.com/7.0.4/examples/material-ui/
You may also be interested to know that for material-ui components, there actually already exists a library that has done most of that manual work for you: redux-form-material-ui.