用数字格式状态反应输入位置

时间:2018-04-27 05:49:18

标签: javascript reactjs numeral.js

我使用数字格式化我的号码从45000004 500 000。 问题在于光标位置 - 当空间数量发生变化时会出错。当我的输入发生变化时,我试图保存光标位置,但是它出了问题。

import React from "react";
import { render } from "react-dom";
import numeral from "numeral";

class App extends React.Component {
    pricePosition = 0;
    priceInput = React.createRef();

    constructor(props) {
        super(props);

        numeral.localeData().delimiters.thousands = " ";

        this.state = {
            price: 4500000 // comes from props
        };
    }

    componentDidUpdate() {
        this.priceInput.current.selectionStart = 
        this.priceInput.current.selectionEnd = this.pricePosition; //tried like this
    }

    handleInputChange = field => ev => {
        this[`${field}Position`] = Number(ev.target.selectionEnd);
        this.setState({
            [field]: Number(ev.target.value.replace(/\D/g, ""))
        });
    };

    render() {
        return (
            <div>
                Price here:
                    <input
                        ref={this.priceInput}
                        value={numeral(this.state.price).format("0,0")}
                        onChange={this.handleInputChange("price")}
                    />
            </div>
        );
    }
}

render(<App />, document.getElementById("root"));

您也可以查看它:codesandbox

2 个答案:

答案 0 :(得分:0)

你必须像下面那样重写componentDidUpdate才能让它发挥作用(丑陋的方式):

    componentDidUpdate() {
        this.priceInput.current.selectionEnd = this.pricePosition + 1; //tried like this
    }

关键是,您只是格式化要在屏幕上显示的值,而不是状态本身,这就是光标与实际长度不匹配的原因。

我建议您重写代码如下:

import React from "react";
import { render } from "react-dom";
import numeral from "numeral";

class App extends React.Component {
    priceInput = React.createRef();

    constructor(props) {
        super(props);

        numeral.localeData().delimiters.thousands = " ";

        this.state = {
            price: 4500000 // comes from props
        };
    }

    handleInputChange = field => ev => {
        const formattedValue = numeral(ev.target.value).format("0,0");
        this[`${field}Position`] = Number(formattedValue.length);
        this.setState({
            [field]: Number(ev.target.value.replace(/\D/g, ""))
        });
    };

    render() {
        return (
            <div>
                Price here:
                    <input
                        ref={this.priceInput}
                        value={numeral(this.state.price).format("0,0")}
                        onChange={this.handleInputChange("price")}
                    />
            </div>
        );
    }
}

render(<App />, document.getElementById("root"));

您现在可以摆脱position变量。

希望这个帮助;)

答案 1 :(得分:0)

我得到了这种hacky解决方案:

import React from "react";
import { render } from "react-dom";
import numeral from "numeral";

class App extends React.Component {
  constructor(props) {
    super(props);

    numeral.localeData().delimiters.thousands = " ";

    this.state = {
      inFocus: false,
      price: 4500000 // comes from props
    };
  }

  changeFocus = () => {
    this.setState(prevState => ({
      inFocus: !prevState.inFocus
    }));
  };

  handleInputChange = field => ev => {
    this.setState({
      [field]: Number(ev.target.value.replace(/\D/g, ""))
    });
  };

  render() {
    const { price, inFocus } = this.state;
    return (
      <div>
        Price here:
        <input
          value={inFocus ? price : numeral(price).format("0,0")}
          onFocus={this.changeFocus}
          onBlur={this.changeFocus}
          onChange={this.handleInputChange("price")}
        />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

当输入处于焦点时,我们使用的是非格式化值。

codesandbox