5
votes

I am using formik in my react application. I have initialized all the form values from a state. But I wanted to update a specific form field if props in the redux store change. Below is my formik form:

<Formik
initialValues={this.state.branchData}
enableReinitialize={true}
onSubmit={this.formSubmit} >
{({ values, setFieldValue }) => (
    <Form >
        <Row>
            <Col lg="12">

                <FormGroup className="col-6">
                    <Input type="select" value={values.StateId} name="StateId" onChange={this.handleChange(setFieldValue)}>
                        <option value='' >Select State</option>
                        {this.props.stateList && this.props.stateList.map((item, i) => (
                            <option key={i} value={item.StateId}>
                                {item.StateName}
                            </option>
                        ))}
                    </Input>
                    {this.validator.message('state', values.StateId, 'required')}
                    <Label className="impo_label">Select State</Label>
                </FormGroup>

                <FormGroup className="col-6">
                    <Field className="form-control" name="GstNo" type="text" maxLength="15" />
                    <Label className="impo_label">GST No</Label>
                    {this.validator.message('gst no', values.GstNo, 'required|min:15|max:15')}
                </FormGroup>


            </Col>
        </Row>
    </Form>
)}

Now, When I change state from the dropdown, an api will get invoke which will return gst no by state id. I want to update the gst no field with the value recieved from the api in the props. If the gst no received is null then I want user to input the gst no, but if gst no is recieved from the api, I want to update the gst no field in form with the value received in props and disable the form input. I cannot update the gstno in this.state.branchData as this will reset the form values with values in this.state.branchData.

Does anyone have any idea about how to achieve this in formik?

3

3 Answers

7
votes

You can enable enableReinitialize property of Formik to update the field.

<Formik
   enableReinitialize={true}
   initialValues={...}
>
....
0
votes

When data comes from api. You can just easy change value of field like this:

setFieldValue('GstNo', valueFromApi)
-1
votes

I defined a state variable for maintaining the gstNo that will be fetched from the API based on the state id selected from the drop-down. Like this:

 this.state = {
   gstNo: null,
 };

So, when the API will get invoked and the response is received, gstNo props will be updated in the redux store.

this.state.gstNo will be updated inside the UNSAFE_componentWillReceiveProps(), when this.props.gstNo changes. Like Below:

if (this.props.gstNo !== nextprops.gstNo) {
  let gstNo;
  if (nextprops.gstNo) {
      gstNo = nextprops.gstNo;
  } 
  else {
      gstNo = null;
  }

 this.setState({
   gstNo: gstNo,
  });

And to assign this.state.gstNo value to formik, I simply wrote this:

<FormGroup className="col-6">
    <Field
        className="form-control"
        name="GstNo"
        disabled={this.state.gstNo}
        type="text"
        maxLength="15"
        value={
            (values.GstNo = this
                .state.gstNo
                ? this.state.gstNo
                : values.GstNo)
        }
    />
    <Label className="impo_label">
        GST No
    </Label>
</FormGroup>

So as soon as this.state.gstNo would be having some value, it would be reflected in formik form's text field and the textbox will be disabled.