【问题标题】:Using React state to allow for temporary invalid numeric input使用 React 状态来允许临时无效的数字输入
【发布时间】:2019-02-03 08:58:20
【问题描述】:

我可能想错了,但我想有两个组件,一个父级和一个子级,其中子级有一个输入元素,用户需要在其中输入一个数字。父组件的回调只会在有效数字上被调用。这是通过 Typescript 和 parseFloat 强制执行的。

class Child extends React.Component {
  state = { number: '' };
  inputChanged = (ev) => {
    const stringy = ev.target.value;
    this.setState({number: stringy});
    const parsed = parseFloat(stringy);
    if (parsed) {
      this.props.numberChanged(parsed);
    }
  }
  render() {
    return <input
      type="text"
      value={this.props.number || this.state.number}
      onChange={this.inputChanged}
    />
  }
}

class Container extends React.Component {
  state = { number: 5 };
  numberSet = (value: number) => {
    this.setState({number: value});
  }
  render() {
    return <Child
      number={this.state.number}
      numberChanged={this.numberSet}
    />;
  }
}

挑战在于我希望能够使用道具设置和更改子组件中的数值。但我也想让用户输入数字。

如果我只依赖道具而不是陈述,那么当他们输入小数点之类的东西时,它们不会显示出来,因为从parseFloat 的角度来看它们是无效的。但是如果我只依赖状态,那么我似乎无法让父组件用新的道具更新子组件。

我也创建了以下CodePen 来重现。请注意您无法在输入字段中键入小数点。我哪里错了?

【问题讨论】:

  • This is enforced via Typescript and parseFloat - TypeScript 一旦运行就不会影响你的代码。 ...decimal points they do not show up because they are invalid from the perspective of parseFloat - 什么?
  • @ethane 可能“强制”是错误的词选择,但我想要表达的是我希望我的上游状态只处理数字,而不是字符串。子组件使用 parseFloat 从输入值进行转换

标签: reactjs typescript


【解决方案1】:

您在这里使用模式使事情复杂化。问题本身可能不正确和错误信息。

但是为了解决您无法使用十进制值的问题, 问题是parseFloat('52.')52 并且由于this.props 的更改,代码在每次更改时都会运行,并且您永远无法成功添加“。” !

使用如下所示的受控组件应该可以解决您的所有问题!

class Child extends React.Component {
    render() {
       return <input
                type="text"
                value = {this.props.number}
                onChange={this.props.numberChanged}
              />
       }
}

class Container extends React.Component {
   state = { number: 5 };
   numberSet = (ev) => {
       let value = event.target.value;
       this.setState({number: value});
   }
   render() {
      return <Child
              number={this.state.number}
              numberChanged={this.numberSet}
             />;
   }
}

React.render(<Container />, document.getElementById('app'));`

【讨论】:

  • 感谢您的回复!我绝对觉得我把它复杂化了。但是,这种方法的问题是,至少在我的应用程序中,现在容器的状态将在用户“键入中”或按下小数点后立即具有数字的非数字值。这是我希望避免的。更具体地说,Container 组件的状态接口在 Typescript 中具有“数字”类型
  • 嗨@Matt,Typescript 只是一种静态类型检查语言,可帮助您在编译为常规 JavaScript 之前及早发现错误。请放心,生产中的代码是良好的旧 JavaScript,没有适当的类型检查系统。防止“中间输入”问题的问题是您永远不能像您提到的问题那样输入十进制数字。 :)
猜你喜欢
  • 2022-01-25
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多