RMT*_*RMT 5 input cursor reactjs
我正在使用React并格式化了一个受控的输入字段,当我写一些数字并在输入字段之外单击时,该输入字段可以正常工作。但是,当我要编辑输入时,光标跳到输入字段中值的前面。这仅发生在IE中,而不发生在例如Chrome中。我已经看到对于某些程序员,光标会跳到该值的后面。因此,我认为我的光标跳到最前面的原因是因为该值在输入字段中向右对齐而不是向左对齐。这是一个senario:
我的第一个输入是1000然后我想将其编辑为10003,但结果是31000
有没有办法控制光标不跳?
Dan*_*ton 35
这是标签的直接替代品<input/>。这是一个简单的功能组件,使用钩子来保留和恢复光标位置:
import React, { useEffect, useRef, useState } from 'react';
const ControlledInput = (props) => {
const { value, onChange, ...rest } = props;
const [cursor, setCursor] = useState(null);
const ref = useRef(null);
useEffect(() => {
const input = ref.current;
if (input) input.setSelectionRange(cursor, cursor);
}, [ref, cursor, value]);
const handleChange = (e) => {
setCursor(e.target.selectionStart);
onChange && onChange(e);
};
return <input ref={ref} value={value} onChange={handleChange} {...rest} />;
};
export default ControlledInput;
Run Code Online (Sandbox Code Playgroud)
...或者如果您愿意的话可以使用TypeScript:
import React, { useEffect, useRef, useState } from 'react';
type InputProps = React.ComponentProps<'input'>;
const ControlledInput: React.FC<InputProps> = (props) => {
const { value, onChange, ...rest } = props;
const [cursor, setCursor] = useState<number | null>(null);
const ref = useRef<HTMLInputElement>(null);
useEffect(() => {
ref.current?.setSelectionRange(cursor, cursor);
}, [ref, cursor, value]);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setCursor(e.target.selectionStart);
onChange?.(e);
};
return <input ref={ref} value={value} onChange={handleChange} {...rest} />;
};
export default ControlledInput;
Run Code Online (Sandbox Code Playgroud)
小智 6
This is my solution:
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = {
name: ""
};
//get reference for input
this.nameRef = React.createRef();
//Setup cursor position for input
this.cursor;
}
componentDidUpdate() {
this._setCursorPositions();
}
_setCursorPositions = () => {
//reset the cursor position for input
this.nameRef.current.selectionStart = this.cursor;
this.nameRef.current.selectionEnd = this.cursor;
};
handleInputChange = (key, val) => {
this.setState({
[key]: val
});
};
render() {
return (
<div className="content">
<div className="form-group col-md-3">
<label htmlFor="name">Name</label>
<input
ref={this.nameRef}
type="text"
autoComplete="off"
className="form-control"
id="name"
value={this.state.name}
onChange={event => {
this.cursor = event.target.selectionStart;
this.handleInputChange("name", event.currentTarget.value);
}}
/>
</div>
</div>
);
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
小智 6
我知道 OP 已经有 5 年历史了,但有些人仍然面临着同样的问题,而且这个页面在 Google 搜索上有很高的知名度。尝试替换:
<input value={...}
Run Code Online (Sandbox Code Playgroud)
和
<input defaultValue={...}
Run Code Online (Sandbox Code Playgroud)
这将解决我在那里见过的大多数情况。
通过您的问题来猜测,您的代码很可能类似于以下内容:
<输入
autoFocus =“ autofocus”
type =“ text”
值= {this.state.value}
onChange = {(e)=> this.setState({value:e.target.value})}
/>
如果处理事件onBlur但本质上是相同的问题,则行为可能会有所不同。实际上,这是预期的行为,许多人已将其称为React的“错误”。
输入控件的值不是控件在加载时的初始值,而是value绑定到的基础this.state。当状态改变时,控件由React重新呈现。
本质上,这意味着该控件由React重新创建并由状态值填充。问题在于,它无法在重新创建之前知道光标位置。
我发现可以解决此问题的一种方法是在重新渲染之前记住光标位置,如下所示:
<输入
autoFocus =“ autofocus”
type =“ text”
值= {this.state.value}
onChange = {(e)=> {
this.cursor = e.target.selectionStart;
this.setState({value:e.target.value});
}}
onFocus = {(e)=> {
e.target.selectionStart = this.cursor;
}}
/>
| 归档时间: |
|
| 查看次数: |
4505 次 |
| 最近记录: |