Skip to content Skip to sidebar Skip to footer

Onchange Handler Doesn't Fire When Using Custom-component

I'm using Formik for validation in a React app. Validation is working correctly, but my onChange handler does not fire:

Solution 1:

Inside Input, the way you have ordered the props passed to your input element means your onChange is being overwritten by Formik's onChange. When you create a Field with a custom component (i.e. Input in your case), Formik passes its FieldProps to the component. FieldProps contains a property field that contains various handlers including onChange.

In your Input component you do this (I've removed the irrelevant props):

<inputonChange={onChange}
    {...field}
/>

See how your own onChange will just get replaced by Formik's onChange() inside field? To make it clearer ...field is basically causing this to happen:

<inputonChange={onChange}onChange={field.onChange}
    // Otherpropsinside "field".
/>

If you were to reorder those the console message will now appear:

<input
    {...field}
    onChange={onChange}
/>

However now your input won't work now because you do need to call Formik's onChange to let Formik now when your input changes. If you want both a custom onChange event and for your input to work properly you can do it like this:

importReactfrom"react";
import { color, scale } from"./variables";

constInput = React.forwardRef(
  ({ onChange, onKeyPress, placeholder, type, label, field, form }, ref) => (
    <divstyle={{display: "flex", flexDirection: "column" }}>
      {label && (
        <labelstyle={{fontWeight:700, marginBottom: `${scale.s2}rem` }}>
          {label}
        </label>
      )}
      <input
        {...field}
        ref={ref}style={{borderRadius: `${scale.s1}rem`,
          border: `1pxsolid ${color.lightGrey}`,
          padding: `${scale.s3}rem`,
          marginBottom: `${scale.s3}rem`
        }}
        onChange={changeEvent => {
          form.setFieldValue(field.name, changeEvent.target.value);
          onChange(changeEvent.target.value);
        }}
        onKeyPress={onKeyPress}
        placeholder={placeholder ? placeholder : "Type something..."}
        type={type ? type : "text"}
      />
    </div>
  )
);

exportdefaultInput;

See it here in action.

Although overall I'm not really sure what you're trying to do. Your form is working fine, you probably don't need a custom onChange but maybe you have some specific use case.

Solution 2:

Let me first make it clear this answer is just for help purpose and I do know that this question has been accepted but I do have some modification for above answer with my version if the above solution doesn't work for anyone

Here onChangeText will return the value of the quantity field

  <Formik
     initialValues={{ product_id: '', quantity: '', amount: '' }}
     onSubmit={(values, actions) => {
        this.submitLogin(values);
     }}

     //some other elements ....
    <Field placeholder='No. of Quantity' name='quantity' component={CustomInputComponent}
        onChangeText={value => {
           console.warn(value); // will get value of quantity
        }}
     />
  />

Outside of your class you can define your component

constCustomInputComponent = ({
   onChangeText,
   field, // { name, value, onChange, onBlur }
   form: { touched, errors, isValid, handleBlur, handleChange, values, setFieldValue }, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc.
   ...props
}) => {
   return (
      <Input {...field} {...props} onBlur={handleBlur(field.name)}onChangeText={value => {
           setFieldValue(field.name, value);
           onChangeText(value); // calling custom onChangeText
        }}
     />
   )
}

Post a Comment for "Onchange Handler Doesn't Fire When Using Custom-component"