在 React 中格式化数字时停止光标跳转 [英] Stop cursor jumping when formatting number in React

查看:27
本文介绍了在 React 中格式化数字时停止光标跳转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 react 组件上有一个输入字段,用于显示项目的行价格(两位小数,带有千位分隔符).我希望在组件首次呈现时显示的值以货币格式显示,并且在用户在字段中键入时也以货币格式保存.

目前我的组件中有以下代码:

var React = require('react');从会计"导入会计;MoneyInput = React.createClass({道具类型:{名称:React.PropTypes.string.isRequired,onChange: React.PropTypes.func.isRequired,值:React.PropTypes.number,错误:React.PropTypes.string,},onChange(事件){//去掉任何货币格式event.target.value = accounting.unformat(event.target.value);//传递值this.props.onChange(事件);},获取值(){返回accounting.formatNumber(this.props.value, 2)},使成为() {返回 (<div className="字段"><输入类型="文本"名称={this.props.name}className="表单控件"值={this.getValue()}onChange={this.onChange}/><div className="input">{this.props.error}</div>

);}});module.exports = MoneyInput;

该代码显示格式正确的数据,但每次我输入一个值时,光标都会跳到数字的末尾.

我明白为什么会发生这种情况(我认为)并且我在这里阅读了几个与在 JavaScript 中不丢失光标位置相关的问题(此处此处).

我的问题是在 React 中处理这个问题的最佳方法是什么?

我认为理想情况下我不想将光标位置存储在状态中(例如,我希望这些是 以 Dan Abramov 语法表示的组件) 那么还有其他方法吗?

解决方案

在正在格式化的 React 的 字段中丢失光标/插入符号位置的一个简单解决方案是管理定位自己:

 onChange(event) {const caret = event.target.selectionStartconst 元素 = event.targetwindow.requestAnimationFrame(() => {element.selectionStart = 插入符号element.selectionEnd = 插入符号})//你的代码}

您的光标位置重置的原因是因为 React 不知道您正在执行什么样的更改(如果您将文本完全更改为更短或更长的内容怎么办?)而您现在负责控制插入符号的位置.

示例: 在我的一个输入文本字段中,我将三个点 (...) 自动替换为省略号.前者是三个字符长的字符串,而后者只有一个.尽管 React 会知道最终结果会是什么样子,但它不再知道将光标放在哪里,因为没有一个明确的逻辑答案.

I have an input field on my react component that shows the line price for an item (two decimal places with thousands separators). I want the value shown to be in money format when the component first renders and also to be kept in money format as user types in the field.

At the moment I have the following code in my component:

var React = require('react');
import accounting from 'accounting';

MoneyInput = React.createClass({
    propTypes: {
        name: React.PropTypes.string.isRequired,
        onChange: React.PropTypes.func.isRequired,
        value: React.PropTypes.number,
        error: React.PropTypes.string,
    },

    onChange(event) {
        // get rid of any money formatting
        event.target.value = accounting.unformat(event.target.value);

        // pass the value on
        this.props.onChange(event);
    },

    getValue() {
        return accounting.formatNumber(this.props.value, 2)
    },

    render() {

        return (
                <div className="field">
                    <input type="text"
                           name={this.props.name}
                           className="form-control"
                           value={this.getValue()}
                           onChange={this.onChange} />
                    <div className="input">{this.props.error}</div>
                </div>
        );
    }
});

module.exports = MoneyInput;

That code displays the data correctly formatted, but every time I enter a value the cursor jumps to the end of the number.

I understand why that's happening (I think) and I've read several questions here related to not losing cursor position in JavaScript (here and here for example).

My question is what's the best way to deal with this in React?

I think that ideally I wouldn't want to store the cursor position in state (e.g. I would want these to be Presentation Components in Dan Abramov syntax) so is there another way?

解决方案

An easy solution for losing cursor/caret position in the React's <input /> field that's being formatted is to manage the position yourself:

    onChange(event) {

      const caret = event.target.selectionStart
      const element = event.target
      window.requestAnimationFrame(() => {
        element.selectionStart = caret
        element.selectionEnd = caret
      })

      // your code
    }

The reason your cursor position resets is because React does not know what kinds of changes you are performing (what if you are changing the text completely to something shorter or longer?) and you are now responsible for controlling the caret position.

Example: On one of my input textfields I auto-replace the three dots (...) with an ellipsis. The former is three-characters-long string, while the latter is just one. Although React would know what the end result would look like, it would not know where to put the cursor anymore as there no one definite logical answer.

这篇关于在 React 中格式化数字时停止光标跳转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆