【问题标题】:How do I create a controlled component with an optional value?如何创建具有可选值的受控组件?
【发布时间】:2021-04-09 10:28:01
【问题描述】:

在 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,但是当我输入一个值时,我得到了错误:

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

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

【问题讨论】:

    标签: reactjs typescript controlled-component


    【解决方案1】:

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

    如果您想将其存储为 数字,请在您的事件处理程序或在为 API 调用制作负载之前执行此操作。

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

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

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

    【讨论】:

    • 也可以使用e.target.valueAsNumber。请注意,当您输入类似123XYZ(类似于Number("123XYZ"))时,其值为NaN
    • 对不起,我这周一直在做其他事情,直到今天才有机会回复这个!
    【解决方案2】:

    当你定义一个组件的 value 属性为 undefined 时,它本质上意味着该组件是一个不受控制的组件。但是,如果在下一个循环中您有一个 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>
    

    【讨论】:

    • ?? 在这里会不会更好
    • @Yoshi 是的,这里也可以使用
    • 问题是我没有真正可以使用的默认值。 0 可能意味着“计数”为 0,但也可能意味着它尚未设置。我需要能够区分这两个选项。
    • 如果是你的情况,你可以忽略警告,它实际上不会影响你的代码的工作
    猜你喜欢
    • 2019-09-07
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 2017-11-18
    相关资源
    最近更新 更多