Mindfuc
Mindfuc

Reputation: 313

React Formik Field onChange event handle

I am trying to handle onChange for Field component in React Formik, but it doesn't work. I also tried to handle it outside Formik component by:

handleChange(e) {
  console.log('changing');
}
<Field type="radio" name="players" value="1" onChange={e => this.handleChange(e)}/>

but I am getting the warning:

A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).

For now my code looks like this:

<Formik
  onChange={() => {
    console.log('changing');
  }}
  onSubmit={(values) => {
    console.log('submitted');
  }}
>
{({ isSubmitting, handleChange }) => (
  <Form>
    <InputWrapper>
       <span>1</span>
       <Field type="radio" name="players" value="1" onChange={handleChange}/>
       <span>2</span>
       <Field type="radio" name="players" value="2" onChange={handleChange}/>
    </InputWrapper>
    <button type="submit" disabled={isSubmitting}>
       {isSubmitting ? 'Loading..' : 'Start'}
    </button>
  </Form>
)}
</Formik>

Any tips/ideas?

Upvotes: 18

Views: 64299

Answers (6)

Chidiebere Ezeokwelume
Chidiebere Ezeokwelume

Reputation: 139

One issue I had when I used the onKeyUp event was that it wouldn't work on input type of dates. So I used onInput Event instead.

    onInput={handleChange}

Works for input type of text and type of dates as well.

Upvotes: 3

Ezeifejafor Dominic
Ezeifejafor Dominic

Reputation: 21

Use onKeyUp={handleChange}. This worked for me when I encountered a similar issue

Upvotes: 1

Jaydev Patidar
Jaydev Patidar

Reputation: 11

 <Grid item xs={12}>
       <Field
           type="email"
           name="email"
           as={FormField}
           label="Email *"
           validate={validate}
           value={emailId}
           onChange={e => {
               setFieldTouched('type');
               handleChange(e)
           }}
       />
       <MDBox>
           <MDTypography component="div" variant="caption" color="error" fontWeight="regular">
               {<div style={{
                   cursor: 'pointer', marginTop: styleMt
               }} onClick={emailStatus != 'ACTIVE' ? handleRestore : ''}>{errorMessages}</div>}
           </MDTypography>
       </MDBox>
   </Grid>

Upvotes: 1

Atif
Atif

Reputation: 51

I found one trick which worked well for me, you can use "values" of formik and call a method passing the "values" as parameter and perform the action using new values.

const handleUserChange = (userId: number) => {
    //userId is the new selected userId
  };


 <Formik
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={handleSubmit}
        enableReinitialize
      >
        {({ isValid, isSubmitting, values }) => (
          <Form>
            <table className="table">
              <tbody>
                <tr>
                  <td>Users</td>
                  <td>
                    <Field name="userId" className="form-control" as="select">
                      <option value="">--select--</option>
                      {data.Users.map((user, index) => (
                        <option key={user.id} value={user.id}>{`User ${index + 1}`}</option>
                      ))}
                    </Field>
                  </td>
                </tr>
                {handleUserChange(values.userId)}
              </tbody>
            </table>

            <div className="row">
              <div className="col-sm-12">
                <SubmitButton label="Save" submitting={isSubmitting} disabled={!isValid || isSubmitting} />
              </div>
            </div>
          </Form>
        )}
      </Formik>

Upvotes: 3

Ray Yecko
Ray Yecko

Reputation: 201

One issue I have found with introducing the onBlur:handleBlur to your Formik Field is that it overrides the Formik Validation.

Use onKeyUp={handleChange}

This solved said problem

Upvotes: 20

You must to use the InputProps of Field like the following...

import { TextField } from 'formik-material-ui';

<Field
  type="radio" 
  name="players" 
  value="2"
  component={TextField} 
  InputProps={{ onBlur:handleBlur }}/>

To use the InputProps in the Field you need to use a component TextField from the formik-material-ui lib.

Another way is use the onKeyUp or onKeyDown, that functions work ok with Field and that functions are like onChange

<Field 
  type="radio" 
  name="players" 
  value="2" 
  onKeyUp =this.handleChange/>

Upvotes: 11

Related Questions