延迟格式化输入

时间:2018-11-14 17:40:01

标签: reactjs

我正在尝试找到一种使小数位数可编辑的方法。

要求: 我希望该值可由其他组件读取。因此,我将其存储在父状态中。
该值可以通过获取的值来更新。当前,这种情况发生在父组件中的多个变量中。
只要输入仅显示x个位置,实际值是否有更多位置都没关系。

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

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

只有C使用固定值。它以“地方”的形式存储在父状态中。尝试编辑C时,它将立即将其转换为固定值,这将移动光标并破坏输入。退格键也无法正常工作。我尝试取消无效的更改-同时,反应不会显示更改,并且第二个数字在最终更新时会弄乱。我尝试使用局部状态,但是这会干扰外部获取,从而将值向下传播,我认为还有其他问题。我只想强制执行小数位,但不能立即执行。某人应该能够键入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>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

因此用parseFloat包装:

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

似乎无法完全取消输入内容,因为该人正在打字,并且退格键大多数都起作用。这就是我现在使用的。我仍然想知道是否有一种方法可以延迟格式化输入。