Prabhat Kumar Singh
Prabhat Kumar Singh

Reputation: 23

Formik error: TypeError: Cannot read property 'value' of undefined

I am new to React and Formik please help me figure this out, I want to use .onSave{product} to pass entered values to another component:

import { Formik } from 'formik';
import * as Yup from 'yup';
export default class ProductForm extends React.Component {
    
    constructor(props) {
      super(props);
      this.onSubmit = this.onSubmit.bind(this);
    }
    
    onSubmit(event){
        event.preventDefault();
        var product = {};
        product.productName = this.refs.productName.value;
        product.quantity = this.refs.quantity.value;
        product.price = this.refs.price.value;
        this.props.onSave(product);
      }

    render() {
        return (
          <Formik initialValues={{productName:"",quantity:"",price:""}} validation`enter code here`Schema={Yup.object().shape({productName:Yup.string().required("Product Name is required"),quantity:Yup.number().required("Quantity is required").positive().integer(),price:Yup.number().required("Quantity is required").positive().integer()}>
    {props=>{
            const{
            values,
            touched,
            errors,
            handleChange,
            handleBlur
        }=props;
        return(<div>
            <h1>Add Product</h1>
            <form autoComplete='off' onSubmit={this.onSubmit}>
                <input type="text"   onChange={handleChange} onBlur={handleBlur}  name="productName" value={values.productName} placeholder="Enter Product Name"/>
                {
                    errors.productName && touched.productName &&(
                    <div className="errorName" >{errors.productName}</div>
                    )
                }<br></br><br></br>
                
                <input type="text"   onChange={handleChange} onBlur={handleBlur} name="quantity" value={values.quantity} placeholder="Enter Quantity"/>
                {
                    errors.quantity && touched.quantity &&(
                    <div className="errorName">{errors.quantity}</div>
                    )
                }<br></br><br></br>
                <input type="text"  onChange={handleChange} onBlur={handleBlur} name="price" value={values.price} placeholder="Enter Price"/>
                {
                    errors.price&&touched.price&&(
                    <div className="errorName">{errors.price}</div>
                    )
                }<br></br><br></br>
                
                <button type="submit" >Submit</button>
            </form>   </div>
        )
    }
    }

</Formik>
      );
    }
}

Upvotes: 2

Views: 6917

Answers (2)

Rohitha
Rohitha

Reputation: 759

There are few things you need to consider:

You have to bind the submit handler to formik and then use it on form

<Formik
        initialValues={{ productName: "", quantity: "", price: "" }}
        validationSchema={Yup.object().shape({
          productName: Yup.string().required("Product Name is required"),
          quantity: Yup.number()
            .required("Quantity is required")
            .positive()
            .integer(),
          price: Yup.number()
            .required("Quantity is required")
            .positive()
            .integer()
        })}
        onSubmit={this.onSubmit}
      >
        {({
          values,
          touched,
          errors,
          handleSubmit,
          handleChange,
          handleBlur
        }) => {
          return (
            <div>
               <h1>Add Product</h1>
              <form autoComplete="off" onSubmit={handleSubmit}>
                 ....
              </form>
            </div>
          )
         );
        }}
      </Formik>

Also there are some changes for event handler for submit:

onSubmit(formData) {
    var product = {};

    product.productName = formData.productName;
    product.quantity = formData.quantity;
    product.price = formData.price;

    console.log(product);

    this.props.onSave(product);
  }

Please check code

Upvotes: 0

upog
upog

Reputation: 5516

try like this

this.inputRef = React.createRef(); // initialize

this.myInput.current // holds the reference to the DOM node

class App extends React.Component {
    constructor(props) {
      super(props) 
      this.inputRef = React.createRef();
    }
  
  handleSubmit = e => {
    e.preventDefault();  
    console.log(this.inputRef.current.value);
  };

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <input type="text" ref={this.inputRef} />
          <button>Submit</button>
        </form>
      </div>
    );
  }
}

Upvotes: 1

Related Questions