Home > Enterprise >  React Formik Warning: A component is changing an uncontrolled input to be controlled
React Formik Warning: A component is changing an uncontrolled input to be controlled

Time:03-20

I am creating a fairly simple todo application in React with TypeScript.

For the form I am using Formik.

The error I get is this when I add value into the input field

3973 Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component

From my previous googling on the topic I learned that the problem most likely is because of the formik InitialValues

Let me show you some code

export interface textFieldProps {
    field: string;
    displayName: string;
}


import { ErrorMessage, Field } from "formik";
import { textFieldProps } from "../interfaces/UtilsProps.interface";

export const TextField = (props: textFieldProps) => {
  return (
    <div className="mb-3">
      <label htmlFor={props.field}>{props.displayName}</label>
      <Field name={props.field} id={props.field} className="form-control" />
      <ErrorMessage name={props.field}>
        {(msg) => <div className="text-danger">{msg}</div>}
      </ErrorMessage>
    </div>
  );
};

Also this

export interface createTodoModel {
    todo: string;
    isComplete: boolean;
}

export interface TodoFormProps {
    model: createTodoModel;
    onSubmit(values: createTodoModel, action: FormikHelpers<createTodoModel>): void;
}

import { Form, Formik } from "formik"
import { TodoFormProps } from "../interfaces/TodoProps.interface"
import * as yup from 'yup'
import { TextField } from "../Utils/TextField"
import Button from "../Utils/Button"

export const TodoForm = (props: TodoFormProps) => {
    return(
        <Formik initialValues={props.model}
        onSubmit={props.onSubmit}
        validationSchema={yup.object({
            name: yup.string().max(50, 'max length is 50 characters').required('You must add an todo').firstLetterUpperCase()
        })}
        >
            {(FormikProps) => (
                <Form>
                    <TextField field='name' displayName='What do you need done?' />
                    <Button children='Add your todo' className='btn btn-outline-primary' disabled={FormikProps.isSubmitting} />
                </Form>
            )}

        </Formik>
    )
}

And this

import { TodoForm } from "../components/Todos/TodoForm"

export const TodoView = () => {
    return(
        <article>
            <TodoForm model={{todo: "", isComplete: false}}
            onSubmit={async value => {
                await new Promise(r => setTimeout(r, 1000));
                console.log(value)
            }}/>
        </article>
    )
}

I however, did not have any luck in my googling.

Would you know a solution to this problem? If so, I would much appreciate it!

Thanks!

CodePudding user response:

you are passing the prop mode down as model={{todo: "", isComplete: false}} which is an object containing these values name is not included and then youre passing these to the formik inital values so the object doesnt contain name value which means its undefined and thats why your getting the error

instead of passing props.model to the <Formik initialValues={props.model}> you need to pass <Formik initialValues={{name: ''}}>

let me know if this help with some calrification this is most likley the soloution to solve the error you are getting

CodePudding user response:

I Changed this

export interface createTodoModel {
    todo: string;
    isComplete: boolean;
}

into this

export interface createTodoModel {
        name: string;
        isComplete: boolean;
    }

and now it works

  • Related