如何使用状态而不是引用来设置文本区域的选择?

how to set a textarea's selection in react using state instead of a ref?

我正在使用 react ref 设置文本区域的 selectionRange,但这与 react "way" 相矛盾。

裁判工作完美。

我想使用状态设置文本区域的 selectionRange,而不是 ref(就像在这个代码片段中一样)

import React, { Component } from 'react';

export default class App extends Component {

  constructor() {
    super();

    this.state = {
      value:"some placeholder text",
    }

    this.textareaRef = React.createRef();
  }

  handleChange=({ target : { value : text } })=>{
   this.setState({value : text});
  };

  componentDidMount(){
    // setting the cursor position to the end of text on mount .
    const textareaObj = textareaRef.current;
    const cursor_pos = this.state.value.length;

    textareaObj.setSelectionRange(cursor_pos , cursor_pos );
    textareaObj.focus();
  }

  render(){
    return (
    <textarea 
      value={this.state.value} 
      onChange={this.handleChange}
      ref={textareaRef}>
    </textarea>
    );
  }
}

您要创建一个 "controlled" component,因为在 React 中应该控制元素的状态而不是 DOM。

您已经完成了一半,只需进行一些调整:https://jsfiddle.net/tombarton/2s5q398c/3/

class TextArea extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
        inputValue: 'Here is some content...'
    }
    this.onTextareaChange = this.onTextareaChange.bind(this);
  }

  onTextareaChange(e) {
    const { value } = e.target;
    this.setState(state => ({
        ...state,
      inputValue: value,
    }))
  }

  render() {
    return (
      <div>
        <textarea value={this.state.inputValue} onChange={this.onTextareaChange} />
      </div>
    )
  }
}

ReactDOM.render(<TextArea />, document.querySelector("#app"))

如您所见,我们将组件状态的值分配给 textarea 元素的 value 属性。为了完成这个过程,我们分配了一个方法来更新元素的 onChange 属性的状态。当 onChange 事件触发时,它被传递到我们的方法中,我们提取更新后的值并更新组件的状态。当我们在 class 之外传递我们的方法时,我们必须将 this 绑定到它,正如您在构造函数中看到的那样。

希望对您有所帮助。

我是这样看的:

export default class App extends Component {

  constructor() {
    super();

    this.state = {
      value:"some placeholder text",
    }
  }

  handleChange=({ target : { value : text } })=>{
    this.setState({value : text});
  };

  render(){
     return (
       <textarea 
         value={this.state.value} 
         onChange={this.handleChange}
         ref={this.setCursorPos}>
       </textarea>
    );
  }

  setCursorPos = (textarea) => {
    const cursor_pos = this.state.value.length;

    textarea.setSelectionRange(cursor_pos , cursor_pos );
    textarea.focus();
  }
}

您想做的是使用 state 设置 selectionStartselectionEnd textarea 属性而不使用 refs?像这样:

render(){
  const { value } = this.state;
  const startingPoint = 0;
  return (
    <textarea 
      value={this.state.value} 
      selectionStart={startingPoint}
      selectionEnd={startingPoint + value.length}
    </textarea>
  );
}

但是目前还不行,大家可以看看<textarea>的所有属性here。所以在这种情况下使用 refs 是完全没问题的。