1

在 React 中,我试图创建一个表单,其中一些值是可选的。我有以下 TypeScript 界面:

export interface DataModel {
    title:      string,
    count?:     number,
}

count是可选的,但如果设置,它必须是一个数字。

我已经像这样设置了我的初始对象:

const INITIAL_VALUE = {
  title: "",
  count: undefined
}

const dataItem = useState(INITIAL_VALUE);

然后我创建一个表单:

<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>

所以count输入最初得到一个值undefined,但是当我输入一个值时,我得到了错误:

一个组件正在改变一个不受控制的输入以被控制

我可以通过用一个值初始化它来避免这种情况,但由于它是可选的,我不想这样做。我该如何处理?

4

2 回答 2

1

当您将组件的 value 属性定义为未定义时,它本质上意味着该组件是一个不受控制的组件。但是,如果在下一个周期中您有一个 value 属性,则组件的行为会从 unControlled 更改为受控。

要解决此问题,您可以为输入添加默认值

<form onSubmit = { handleSave }>
  <input
    name     = "title"
    value    = { dataItem.title || ''}
    onChange = { handleChange }
    type     = "text"
    placeholder = "Enter title"
  />
  <input
    name        = "count"
    value       = { dataItem.count || 0}
    onChange    = { handleChange }
    type        = "number"
  />
</form>
于 2021-04-09T10:31:33.820 回答
1

您应该提供适当的初始值。而且,这可能是0或空字符串 - ""。即使输入类型为,空字符串也应该没问题number。因为e.target.value总是字符串

如果要将其存储为数字,请在事件处理程序中使用parseIntparseFloatNumber(检查详细信息以确保它们符合需要)将值转换为数字,或者在为 API 调用生成有效负载之前执行此操作。

因此,您应该简单地将接口和初始值定义为:

export interface DataModel {
  title: string;
  count: number | ""; // count is a number or empty string
}

const INITIAL_VALUE = {
  title: "",
  count: "",
};

这样,组件始终保持为受控组件。

于 2021-04-10T12:30:37.447 回答