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