Unable to set state of TextField to undefined using React hook

969 views Asked by At

I would like to have the initial state for a date TextField be set to undefined until the user has selected a date, and then allow the user to easily reset the date back to undefined.

In the following code, the Reset button will properly reset parameters.count state to 0, but it will not reset parameters.date to undefined. Is undefined treated specially in this case?

import React, { useState } from "react";
import { Button, TextField } from "@material-ui/core";

import "./App.css";

export type Parameters = {
  count: number;
  date?: string;
};

const initialParameters: Parameters = {
  count: 0,
  date: undefined,
};

export const App: React.FC = () => {
  const [parameters, setParameters] = useState<Parameters>(initialParameters);

  const handleCountChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setParameters({
      ...parameters,
      count: Number(event.target.value),
    });
  };

  const handleDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setParameters({
      ...parameters,
      date: event.target.value,
    });
  };

  const resetState = () => {
    setParameters(initialParameters);
  };

  return (
    <div className="App">
      <TextField
        type="number"
        label="Count"
        value={parameters.count}
        onChange={handleCountChange}
      />
      <TextField
        label="Date"
        type="date"
        value={parameters.date}
        onChange={handleDateChange}
        InputLabelProps={{
          shrink: true,
        }}
      />
      <Button onClick={resetState}>Reset</Button>
    </div>
  );
};
1

There are 1 answers

0
johnthagen On BEST ANSWER

The solution based on @cbr's comment is to coerce undefined to "" before passing to TextField.

import React, { useState } from "react";
import { Button, TextField } from "@material-ui/core";

import "./App.css";

export type Parameters = {
  count: number;
  date?: string;
};

const initialParameters: Parameters = {
  count: 0,
  date: undefined,
};

export const App: React.FC = () => {
  const [parameters, setParameters] = useState<Parameters>(initialParameters);

  const handleCountChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setParameters({
      ...parameters,
      count: Number(event.target.value),
    });
  };

  const handleDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setParameters({
      ...parameters,
      date: event.target.value,
    });
  };

  const resetState = () => {
    setParameters(initialParameters);
  };

  // TextField expects blank string to represent no value.
  const dateDisplay = parameters.date ? parameters.date : "";
  return (
    <div className="App">
      <TextField
        type="number"
        label="Count"
        value={parameters.count}
        onChange={handleCountChange}
      />
      <TextField
        label="Date"
        type="date"
        value={dateDisplay}
        onChange={handleDateChange}
        InputLabelProps={{
          shrink: true,
        }}
      />
      <Button onClick={resetState}>Reset</Button>
    </div>
  );
};