This is probably rather an easy question yet I'd like to learn a better way if there is (I stripped out the return section to keep the relevant part only):
interface FormPattern {
id: string;
name: string;
email: string;
age: number;
}
const AddUser = () => {
const [inputData, setInputData] = useState<FormPattern>({
id: "",
name: "",
email: "",
age: undefined,
});
}
The problem I have is to set an initial value for number type here. The code snippet above throws an error by Typescript since age must be number and it doesn't accept undefined. I tried this one instead :
interface FormPattern {
id: string;
name: string;
email: string;
age: number | undefined;
}
const AddUser = () => {
const [inputData, setInputData] = useState<FormPattern>({
id: "",
name: "",
email: "",
age: undefined,
});
}
This works fine. However, when I try to reset the state by using setInputData
with same pattern, age:undefined
doesn't reset the number input
field in the form.
Is there a better way to set initial value or reset / clear the value of number
type for Typescript?
Edit : Here is the component
import { useState } from "react";
import nextId from "react-id-generator";
import Button from "../Button";
import { Form, FormWrap, Label, Input, Select, Textarea } from "../FormInputs";
import FormCard from "../FormInputs/FormCard";
interface FormPattern {
id: string;
name: string;
email: string;
age: number | undefined;
}
const AddUser = () => {
const formDefaults = {
id: "",
name: "",
email: "",
age: undefined,
};
const [userList, setUserList] = useState<FormPattern[]>([]);
const [inputData, setInputData] = useState<FormPattern>(formDefaults);
const submitHandler = (e: any) => {
e.preventDefault();
if (!inputData.name || !inputData.email) {
return;
}
const entryId = nextId();
setUserList([
...userList,
{
id: entryId,
name: inputData.name,
email: inputData.email,
age: inputData.age,
},
]);
setInputData(formDefaults);
};
const inputHandler = (e: any) => {
let newValue = e.target.value;
if (e.target.type === "checkbox") {
newValue = e.target.checked;
}
setInputData({ ...inputData, [e.target.name]: newValue });
};
return (
<FormCard>
<Form onSubmit={submitHandler}>
<FormWrap>
<Label htmlFor="name">Name</Label>
<Input
type="text"
name="name"
value={inputData.name}
onChange={inputHandler}
/>
</FormWrap>
<FormWrap>
<Label htmlFor="email">Email</Label>
<Input
type="text"
name="email"
value={inputData.email}
onChange={inputHandler}
/>
</FormWrap>
<FormWrap>
<Label htmlFor="age">Age</Label>
<Input
type="number"
name="age"
min="0"
value={inputData.age}
onChange={inputHandler}
/>
</FormWrap>
<Button type="submit" size="lg" block={true} theme="red" round="sm">
Submit Button
</Button>
</Form>
</FormCard>
);
};
export default AddUser;
CodePudding user response:
You can try using null
instead of undefined
:
interface FormPattern {
id: string;
name: string;
email: string;
age: number | null;
}
const AddUser = () => {
const [inputData, setInputData] = useState<FormPattern>({
id: "",
name: "",
email: "",
age: null,
});
}
Can you provide input element code, or working sandbox example? Because the issue is not with useState, but at some other place. I believe that useState handles "reset" correctly.
Edit:
You cannot use null or undefined when you use input. You should use empty string instead. For example: https://codesandbox.io/s/inspiring-wilson-gs5mj7?file=/src/App.tsx
Also you can use NaN, but keep in mind that it only works if input type is number.