Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

formik warning, A component is changing an uncontrolled input of type text to be controlled

I am developing a dynamic form in React JS, when the user clicks on the Add button, the Register form is added to screen. In the Register form I am using formik for validation.

The form is dynamically adding successfully but whenever I start entering any input in the input box, I am getting the following error in the console:

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). Decide between using a controlled or uncontrolled input element 
for the lifetime of the component. 

I am not sure where it is wrong. Below is my dynamic form rendering code -

Account.js

import React, { Component } from 'react';
import axios from 'axios';
import {
    Card, CardBody, CardHeader,Button,Col, Row, Form, Container
} from 'reactstrap';
import { Formik, Field, ErrorMessage } from 'formik';
import WrapperForm from './WrapperForm'

class Account extends Component {

  state = {
    wrapperForm: [{}]
  }

  constructor(props) {
    super(props);
  }

  addUser = () => {
    this.setState((prevState) => ({
      wrapperForm: [...prevState.wrapperForm, {}],
    }));
  }

  render() {
    let { wrapperForm } = this.state
    return (
      <Form>
        <Container className="themed-container" fluid={true}>
          <button type="button" onClick={this.addUser}>Add User</button>
          <WrapperForm wrapperForm={wrapperForm} />
        </Container>
      </Form>
    );
  }
}

export default Account;  

WrapperForm.js

const WrapperForm = (props) => {
  return (
    props.wrapperForm.map((val, idx)=> {
      return (
        <Formik 
          key={idx}
          initialValues={{
            email: props.wrapperForm[idx].email || '',
            password: props.wrapperForm[idx].password || '',
            firstName: props.wrapperForm[idx].firstName || '',
            lastName: props.wrapperForm[idx].lastName || '',
            zipCode: props.wrapperForm[idx].zipCode ||  ''
          }}
        >
          {({ values }) => (
            <Row style={{ marginBottom: "2em" }}>
              <Card>
                <CardHeader>Register</CardHeader>
                <CardBody>
                  <Temp index={idx} />
                </CardBody>
              </Card>
            </Row>
          )}
        </Formik>  
      )
    })
  )
}

Temp.js

const Temp = ({ index }) => {
  let passwordId = 'password-'+ index;
  let firstNameId = 'firstName-'+ index;
  let lastNameId = 'lastName-'+ index;
  let zipCodeId = 'zipCode-'+ index;

  return (
    <Card body outline color="primary">
      <CardTitle>Create Profile</CardTitle>
      <Row form>
        <Col md={6}>
          <Field
            className="email"
            component={customInputForm}
            data-id={index}
            id="email"
            label="Email"
            name="email"
            placeholder="Email"
            type="email"
          />
        </Col>
      </Row>
    </Card>
  )
}
like image 854
ppb Avatar asked Apr 05 '20 19:04

ppb


People also ask

Is formik controlled or uncontrolled?

It's the world's leading library for building forms in React. Formik is a complete solution that helps you to implement form validation, keep track of visited fields, and handle form submission in an efficient and robust manner. It is based on the concept of a controlled component.

Is changing an uncontrolled input to be controlled?

The warning "A component is changing an uncontrolled input to be controlled" occurs when an input value is initialized to undefined but is later changed to a different value. To fix the warning, initialize the input value to an empty string, e.g. value={message || ''} . Here is an example of how the error occurs.

What is formikBag?

formikBag is an object that contains different methods and fields to act upon your formik form. I need access to formikBag.submitForm , and formikBag.isSubmitting inside the handleClick function. Eg: isSubmitting helps me with button styling while the form is submitting.

What does formik handleChange do?

Using Formik's handleChange The handleChange method updates the form values based on the input's name attribute that was changed.


1 Answers

I found one solution, maybe it will help someone. You need to create dynamic initialValues for formik as:

let passwordId = 'password-'+ idx ;
let firstNameId = 'firstName-'+ idx;
let lastNameId = 'lastName-'+ idx;
let zipCodeId = 'zipCode-'+ idx;

return (
  <Formik 
      key={idx}
      initialValues={{
          email: props.wrapperForm[idx].email || '',
          [passwordId]: props.wrapperForm[idx].password || '',
          [firstNameId]: props.wrapperForm[idx].firstName || '',
          [lastNameId]: props.wrapperForm[idx].lastName || '',
          [zipCodeId]: props.wrapperForm[idx].zipCode ||  ''
      }}
  >
)
like image 105
ppb Avatar answered Sep 28 '22 08:09

ppb