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!
I Changed this
export interface createTodoModel {
todo: string;
isComplete: boolean;
}
into this
export interface createTodoModel {
name: string;
isComplete: boolean;
}
and now it works