React: Как читать внешние события onChange

Как читать события изменения внешнего текста в реакции.

Расширения, такие как Grammarly и Auto Text Expander обновлять текст внутри textarea, но после изменения не реагирует onChange или onInput. В результате состояние не обновляется, и условие несовместимо (разные значения в textarea и состоянии компонента). Один из способов - прочитать значение dom для submit, но это не идеальное решение для моего сценария, так как некоторые другие действия зависят от текущего значения текстового поля. Любое хорошее решение?

PS: Я прошу об общем решении. Изменение кода расширений не является вариантом.

Ответ 1

У вас может быть такая проблема, когда вы используете плагин ввода jQuery, а плагин использует метод .attr вместо метода .prop, который запускает событие onChange. В этом случае вам нужно полагаться на обработчики обратного вызова, предоставляемые плагином.

В вашем случае вряд ли найдется такой обработчик обратного вызова. (Никогда не мешает проверять, доступен ли код.) Тогда единственным вариантом является опрос, который является уродливым, но неизбежным.

Ответ 2

Хотя это не написано с учетом такого сценария, возможно https://github.com/erikras/react-native-listener может помочь вам достичь того, что вы хотите?!

Ответ 3

Я проверил это, и он отлично работает для меня. Правописание и грамматика, исправленные Grammarly, обновляют состояние компонента.

<textarea value={this.state.testText} onChange={(e) => {this.setState({testText: e.target.value} )}} />

Ответ 4

Вы можете добавить прослушиватель событий onchange всего или определенного текстового поля внутри componentDidMount (см. фрагмент для реализации). Это обновит состояние внутри React. Отрывок хорошо рассмотрен с комментарием. Это должно помочь вам!

class KeyTrace extends React.Component {
  constructor(props) {
    super(props)
    this.setValueToState = this.setValueToState.bind(this)
    this.state = {} //initial state
  }
  setValueToState(e) {
   this.setState({
     [e.target.id]: e.target.value //set the new value in the state as {[id]: [value]} pair
   })
  }
  componentDidMount() {
    const textareas = document.querySelectorAll('textarea') //finds all textarea in the DOM
    const textareasArray = [...textareas] //convert the HTML Collection into array
    textareasArray.forEach((el) => { //loop through the array
      if (el.id === 'update') //add onchange listener for specific textareas (optional)
        el.onchange = this.setValueToState //add a event listener
    })

  }
  render(){
    console.log(this.state)
    return false
  }
}

ReactDOM.render(<KeyTrace/>, document.getElementById('react'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="non-react">
  Changes will be stored in react state
  <br/>
  <textarea id="update"></textarea>
  <br/>Changes will not be stored in react state
  <br/>
  <textarea id="wont-update"></textarea>
  <br/>
</div>
<div id="react"></div>