使用 React 更改文本区域中的光标位置

新手上路,请多包涵

我在 React 中有一个文本区域,我想把它变成一个“记事本”。这意味着我希望“tab”键缩进而不是散焦。我查看了 这个答案,但我无法让它与 React 一起使用。这是我的代码:

 handleKeyDown(event) {
    if (event.keyCode === 9) { // tab was pressed
        event.preventDefault();
        var val = this.state.scriptString,
            start = event.target.selectionStart,
            end = event.target.selectionEnd;

        this.setState({"scriptString": val.substring(0, start) + '\t' + val.substring(end)});
        // This line doesn't work. The caret position is always at the end of the line
        this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1;
    }
}
onScriptChange(event) {
   this.setState({scriptString: event.target.value});
}
render() {
    return (
        <textarea rows="30" cols="100"
                  ref="input"
                  onKeyDown={this.handleKeyDown.bind(this)}
                  onChange={this.onScriptChange.bind(this)}
                  value={this.state.scriptString}/>
    )
}

当我运行这段代码时,即使我在字符串中间按下“tab”键,我的光标也总是出现在字符串的末尾。任何人都知道如何正确设置光标位置?

原文由 Discombobulous 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

您必须在状态更新 更改光标位置( setState() 不会立即变异 this.state

为此,您必须将 this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1; 包装在一个函数中,并将其作为第二个参数传递给 setState (回调)。

 handleKeyDown(event) {
      if (event.keyCode === 9) { // tab was pressed
          event.preventDefault();
          var val = this.state.scriptString,
          start = event.target.selectionStart,
          end = event.target.selectionEnd;
          this.setState(
              {
                  "scriptString": val.substring(0, start) + '\t' + val.substring(end)
              },
              () => {
                  this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1
              });
      }
 }

小提琴手

原文由 QoP 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于正在寻找快速 React Hooks (16.8+) 光标位置示例的任何人:

 import React, { useRef } from 'react';

export default () => {
  const textareaRef = useRef();
  const cursorPosition = 0;

  return <textarea
    ref={textareaRef}
    onBlur={() => textareaRef.current.setSelectionRange(cursorPosition, cursorPosition)}
  />

}

在此示例中, setSelectionRange 用于在输入不再聚焦时将光标位置设置为 cursorPosition 的值。

关于 useRef 的更多信息,可以参考React官方文档的 Hook部分

原文由 Chris Dolphin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题