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>