admin管理员组

文章数量:1327248

How to read the external text change events in react.

The extensions like Grammarly and Auto Text Expander update the text inside textarea, but no react onChange or onInput event is fired after the change. As the result, state is not updated and the condition is inconsistent (different values in textarea and ponent's state). One way is to read the dom value on submit, but that's not the perfect solution for my scenario, as some other actions depends on the current value of the textarea. Any good solution?

PS: I'm asking for a generic solution. Changing extensions code is not an option.

How to read the external text change events in react.

The extensions like Grammarly and Auto Text Expander update the text inside textarea, but no react onChange or onInput event is fired after the change. As the result, state is not updated and the condition is inconsistent (different values in textarea and ponent's state). One way is to read the dom value on submit, but that's not the perfect solution for my scenario, as some other actions depends on the current value of the textarea. Any good solution?

PS: I'm asking for a generic solution. Changing extensions code is not an option.

Share Improve this question asked Oct 24, 2016 at 7:23 manishmanish 9562 gold badges12 silver badges35 bronze badges 5
  • 2 Well, the thing is, the input or textarea HTML doesn't change on direct modifications of .value property employed by those extensions. You'll probably have to poll document.activeElement.value periodically if it's a text element. – woxxom Commented Oct 24, 2016 at 8:28
  • polling not a perfect solution for me. Any other idea? – manish Commented Oct 24, 2016 at 8:50
  • Well, since those extensions change the value right after some keydown or other hardware event, you can listen to those and poll for a while, then stop. – woxxom Commented Oct 24, 2016 at 8:52
  • 2 How do you get a mutation observer to detect a value change of a textarea? suggests that approaches other than polling are unfortunately unlikely. – Xan Commented Oct 27, 2016 at 11:10
  • This works fine for me. Question is not relevant anymore. – Kamlesh Tajpuri Commented Jun 8, 2019 at 19:38
Add a ment  | 

3 Answers 3

Reset to default 2

I checked this and it works fine for me. Spelling and grammar corrected by Grammarly updates the ponent state.

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

You can have this kind of problem when you use a jQuery input plugin and the plugin uses .attr method instead of .prop method, which triggers an onChange event. In this case, you need to rely on callback handlers provided by the plugin.

In your case it seems unlikely there's such a callback handler. (It never hurts to check, if the code is available.) Then, the only option seems to be polling, which is ugly but inevitable.

You can add an onchange event listener of all or a specific textarea inside ponentDidMount (see the snippet for implementation). This will update the state inside React. The snippet is well addressed with the ment. It should help you!

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
   })
  }
  ponentDidMount() {
    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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./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>

PS. You need to blur(click outside the textarea) the textarea to fire the onchange event. Else, you can use onkeypress instead of onchange.

本文标签: javascriptReact How to read external onChange eventsStack Overflow