4
votes

I am new to ReactJS and using formik in my web application. Inside the form, I have to set the value of a field based on the value entered by the user in another field.

Below is my form:

<Formik
   initialValues={this.state.data}
   enableReinitialize={true}
   onSubmit={this.formSubmit} >
   {({ values, setFieldValue }) => (
   <Form>
      <FormGroup>
         <Field className="form-control" name="Price" type="number">
         </Field>
         <Label className="impo_label">Price</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" name="Qty" type="number">
         </Field>
         <Label className="impo_label">Qty</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" value={values.Price*values.Qty} name="Amount" type="number">
         </Field>
         <Label className="impo_label">Amount</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" name="Discount" type="number">
         </Field>
         <Label className="impo_label">Discount</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" name="Discount" type="number">
         </Field>
         <Label className="impo_label">Discount</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" value={(values.Amount * values.Discount)/100} name="FinalAmount" type="number">
         </Field>
         <Label className="impo_label">FinalAmount</Label>
      </FormGroup>
   </Form>
   )}
</Formik>

In this form, I want to set value for Amount based on the price and quantity entered by the user. For this, I have used value={values.Price*values.Qty}, that is showing the value properly in textbox but the value is not set in values.Amount due to which FinalAmount is not being evaluated properly.

I know the issue here, I have to use setFieldValue to update the {values.Amount}.Likewise, I had to use setFieldValue for {values.FinalAmount} also and that too on the change of Price and Qty, because change in either price or qty should be reflected in both Amount as well as FinalAmount. Also, I have to use setFieldValue for FinalAmount on change of Discount. Is there any other way through which I can directly set the value for {values.Amount} as well as {values.FinalAmount} without writing setFeildValue on change of Price, Qty and Discount. Something like using value={values.Price*values.Qty} for Amount should update {values.Amount}.

2

2 Answers

3
votes

Finally, after trying various ways, I got the solution for this. I simply set the Amount and FinalAmount inside value attribute like value={values.Amount = values.Price*values.Qty}. So the {values.Amount} field was updated without using setFieldValue. As a result, based on {values.Amount}, {values.FinalAmount} was evaluated properly. I didn't knew we can set the formik values directly like this without using setFieldValue. Now my final form becomes:

<Formik
   initialValues={this.state.data}
   enableReinitialize={true}
   onSubmit={this.formSubmit} >
   {({ values, setFieldValue }) => (
   <Form>
      <FormGroup>
         <Field className="form-control" name="Price" type="number">
         </Field>
         <Label className="impo_label">Price</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" name="Qty" type="number">
         </Field>
         <Label className="impo_label">Qty</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" value={values.Amount = values.Price*values.Qty} name="Amount" type="number">
         </Field>
         <Label className="impo_label">Amount</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" name="Discount" type="number">
         </Field>
         <Label className="impo_label">Discount</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" name="Discount" type="number">
         </Field>
         <Label className="impo_label">Discount</Label>
      </FormGroup>
      <FormGroup>
         <Field className="form-control" value={values.FinalAmount = (values.Amount * values.Discount)/100} name="FinalAmount" type="number">
         </Field>
         <Label className="impo_label">FinalAmount</Label>
      </FormGroup>
   </Form>
   )}
0
votes

if you are using the useFormik() hook, and you wish to compute field/input values yourself, all that is required is you set the dirty:true and pass to the hook.

const formik = useFormik({ initialValues, onSubmit, dirty: true});