首页 > 解决方案 > 延迟格式化输入

问题描述

我正在尝试找到一种方法来制作带小数的可编辑数字。

要求:我希望其他组件可以读取该值。出于这个原因,我将它存储在父状态中。
该值可以由获取的值更新。目前这发生在父组件中的多个变量上。
只要输入仅显示 x 个位置,实际值是否具有更多位置并不重要。

转换为固定值时遇到问题 - 特别是在 Chrome 上,它恰好是首选浏览器。我写了一个codepen:

https://codepen.io/j1dopeman/pen/wQJNzQ

只有 C 使用固定值。它作为“地点”存储在父状态中。尝试编辑 C 时,它会立即将其转换为固定值,从而移动光标并破坏输入。Backspace 也无法按预期工作。我已经尝试对无效的更改进行去抖动 - 同时反应不会显示更改,并且第二个数字在最终更新时会变得混乱。我尝试过使用本地状态,但这会干扰将值向下传播的外部获取,我认为还有其他问题。我只想强制执行小数位,但不是立即执行。有人应该能够键入 1.25 或退格键并键入一个新数字,然后它会在一秒钟后进行转换。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputs: {
        a: { val: 0 },
        b: { val: 0 },
        c: { val: 1.5, places: 2 },
        d: { val: 0 },
        e: { val: 0 },
        f: { val: 0 }
      }
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(value) {
    const update = newVals => {
      return state => {
        let nv = {};
        for (let [key, val] of Object.entries(newVals)) {
          nv = { ...nv, [key]: Object.assign(state.inputs[key], val) };
        }
        const ni = Object.assign(state.inputs, nv);
        return { inputs: ni };
      };
    };
    //-----
    this.setState(update(value));
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1>Calc</h1>
        </header>
        <InputArea
          inputs={this.state.inputs}
          onInputChange={this.handleInputChange}
        />
      </div>
    );
  }
}

class InputArea extends React.Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(value) {
    this.props.onInputChange(value);
  }

  render() {
    const inputList = [];

    for (let [key, value] of Object.entries(this.props.inputs)) {
      inputList.push(
        <Variable
          key={key}
          name={key}
          value={value}
          onInputChange={this.handleInputChange}
        />
      );
    }

    return (
      <div className="input">
        <h1>Input</h1>
        <div className="input-area">{inputList}</div>
      </div>
    );
  }
}

class Variable extends React.Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(e) {
    let v = this.props.value;
    v.val = Number(e.target.value);
    this.props.onInputChange({ [this.props.name]: v });
  }

  render() {
    const label = this.props.name;
    let val = this.props.value.val;
    if (this.props.value.places !== undefined)
      val = val.toFixed(this.props.value.places);

    return (
      <div className="flex-row">
        <label>{label}</label>
        <input
          className="variable-input"
          type="number"
          name={label}
          value={val}
          step="any"
          onChange={this.handleInputChange}
        />
      </div>
    );
  }
}

标签: reactjs

解决方案


所以用 parseFloat 包装:

  val = parseFloat(val.toFixed(this.props.value.places));

似乎并没有完全搞砸输入,因为这个人正在打字并且退格键大部分都有效。所以这就是我现在使用的。我仍然想知道是否有办法延迟格式化输入。


推荐阅读