Home > Enterprise >  Setting an initial undefined value for number type in Typescript
Setting an initial undefined value for number type in Typescript

Time:04-14

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.

  • Related