使用 KeyboardDatePicker 时获取“组件正在将不受控制的输入更改为受控制 (...)”

Bru*_*res 1 typescript reactjs react-hooks

可以在此链接中找到可重现的示例。

我从 React 和 Hooks 开始。目前,我正在尝试构建一个配置表单来生成一些报告。我正在构建的整个表单的第一个子组件是一个Filter只有两个日期(开始日期和结束日期)的组件。

在名为的外部组件中,Configuration我具有表单状态,并且开始和结束日期通过 props 传递给Filter组件以及onPeriodChange回调:

export const Configuration: React.FC = () => {
  const [periodState, setPeriodState] = useState<Period>({
    startDate: '',
    endDate: '',
  });

  const handlePeriodChange = useCallback(
    (field: keyof Period, value: string) =>
      setPeriodState({ ...periodState, [field]: value }),
    [periodState],
  );

  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <form name="configuration">
        <Filters period={periodState} onPeriodChange={handlePeriodChange} />
      </form>
    </MuiPickersUtilsProvider>
  );
};
Run Code Online (Sandbox Code Playgroud)

然后,将 props 传递给KeyboardDatePicker组件中的组件Filter

export const Filters: React.FC<FilterProps> = (filterProps: FilterProps) => {
  const { period, onPeriodChange } = filterProps;

  return (
    (...)
      <KeyboardDatePicker
        disableToolbar
        fullWidth
        variant="inline"
        format="dd/MM/yyyy"
        id="start-date"
        label="Data de descarga inicial:"
        value={period.startDate}
        onChange={(date) => {
          onPeriodChange(
            'startDate',
            date instanceof Date && !Number.isNaN(date)
              ? date.toISOString()
              : '',
          );
        }}
        required
        KeyboardButtonProps={{
          'aria-label': 'change date',
        }}
      />
    (...)
  );
};
Run Code Online (Sandbox Code Playgroud)

在第一次渲染中,组件显示为无效:

无效组件

当我更改第一个组件的值时,我收到控制台警告(您可以在沙箱中重现此行为):

警告:组件正在将不受控制的输入更改为受控制。这可能是由于值从未定义的值更改为已定义的值引起的,这种情况不应该发生。在组件的生命周期内决定使用受控或非受控输入元件。

我不知道为什么会收到此错误,因为开始日期和结束日期的初始值是空字符串(并且不是未定义的)。你能指出我的错误在哪里吗?谢谢!

axt*_*tck 5

这是因为 period 值从空字符串更改为 a Date,在您的初始值中,您还应该传递 a Date

警告:组件正在将不受控制的输入更改为受控制。这可能是由于值从未定义的值更改为已定义的值引起的,这种情况不应该发生。在组件的生命周期内决定使用受控或非受控输入元件。

界面更新

export interface Period {
  startDate: Date;
  endDate: Date;
}
Run Code Online (Sandbox Code Playgroud)

初始状态更新

const [periodState, setPeriodState] = useState<Period>({
  startDate: new Date(),
  endDate: new Date()
});
Run Code Online (Sandbox Code Playgroud)