在 React 中将光标发送到输入值的末尾

IT技术 javascript reactjs
2021-05-08 18:34:49

单击删除(以编辑最后一个输入条目)时,我动态地将一个值传递给我的输入字段。

我可以看到,在 Chrome 中,一旦输入值被呈现,光标就会显示在单词的开头,而在 Safari 和 Firefox 中,则显示在值的末尾,但最后一个字母被删除。

如何在不删除最后一个字母的情况下始终看到最后的光标(除非我按退格键两次)?

  tagEvent(e) {
    const tag = this.text.value;
    const tagGroup = tag.split(" ");
    const tiles = this.props.tiles;
    const hasTiles = Object.keys(tiles).length > 0;

    if(e.keyCode === 32 || e.keyCode === 13){
      e.preventDefault();
      tagGroup.map(tag => this.props.addTile(tag));
      this.tagForm.reset();
    }

    if(e.keyCode === 8 && hasTiles && tag === '' ) {
      this.props.editLastTile();
      this.tagForm.reset();
    }
  }

  render() {
    return (
      <div className="input-wrapper">
        <form ref={(input) => this.tagForm = input}>
          <input ref={(input) => this.text = input}
                 type="text"
                 name="new-item"
                 placeholder="type and press space"
                 autoComplete="off"
                 defaultValue={this.props.value}
                 onKeyDown={(e) => this.tagEvent(e)} />
        </form>
      </div>
    )
  }

这是带有完整代码的 Pen

非常感谢您的帮助!

3个回答

您可以显式设置光标位置,为此将其添加到Input

componentDidUpdate(prevProps) {
    if (prevProps.value !== this.props.value) {
        this.text.selectionStart = this.text.value.length;
        this.text.selectionEnd = this.text.value.length;
    }
}

为防止删除最后一个字符,请在e.preventDefault()后面添加if(e.keyCode === 8 && hasTiles && tag === '' ) {

编辑

另一个简单的解决方案:

<input ref={ref => ref && ref.focus()}
    onFocus={(e)=>e.currentTarget.setSelectionRange(e.currentTarget.value.length, e.currentTarget.value.length)}
    />

ref触发焦点,并触发onFocus计算结束并相应地设置光标。

对于那些来这里尝试使用 react hooks 的人 🙌

一个简单的 texfield 组件,可将输入类型切换为密码/文本,这是典型情况,您希望允许用户通过单击按钮来切换类型和查看值来查看他们的密码。

function TextField() {
  const [type, setType] = useState('text');
  const inputRef = useRef(null);
  const onToggle = useCallback(() => {
    setType(current => type === 'text' ? 'password' : 'text');
    // Setting focus here
    inputRef.current.focus();
  }, []);
  useEffect(() => {
    // Moving cursor to the end
    inputRef.current.selectionStart = inputRef.current.value.length;
    inputRef.current.selectionEnd = inputRef.current.value.length;
  }, [type]);

  return (
    <div>
      <input
        ref={inputRef}
        type={type}
       />
       <button onClick={onToggle}>toggle type</button>
    </div>
  );
}