In React, I'm trying to create a form in which some values are optional. I have the following TypeScript interface:
export interface DataModel {
title: string,
count?: number,
}
count
is optional, but if it's set, it has to be a number.
I've set up my initial object like this:
const INITIAL_VALUE = {
title: "",
count: undefined
}
const dataItem = useState(INITIAL_VALUE);
Then I create a form:
<form onSubmit = { handleSave }>
<input
name = "title"
value = { dataItem.title}
onChange = { handleChange }
type = "text"
placeholder = "Enter title"
/>
<input
name = "count"
value = { dataItem.count}
onChange = { handleChange }
type = "number"
/>
</form>
So the count
input is initially getting a value of undefined
, but then when I enter a value, I get the error:
A component is changing an uncontrolled input to be controlled
I can avoid this by initializing it with a value, but as it's optional I don't want to do that. How should I handle this?
You should provide a proper initial value. And, that could be 0
or empty string - ""
. Empty string should be fine even when input type is number
. Because e.target.value
is always string.
If you want to store it as a number, turn the value to number using parseInt, parseFloat or Number (check details to make sure they fit the need) in your event handler or do this before making payload for the API call.
Hence, you should simply define the interface and initial values as:
export interface DataModel {
title: string;
count: number | ""; // count is a number or empty string
}
const INITIAL_VALUE = {
title: "",
count: "",
};
This way the component always stays as a controlled component.