8

I know this is not "the react way," or any other version of ideal. But circumstances are beyond my control and I need to find a work around or "hack". That being said....

I am looking for a way to programmatically enter text content into a <textarea> element that is rendered as part of a react component. The catch is I need to do this from outside of the react app. The react app was written, compiled, minified, and delivered by someone else.

The <textarea> has an id attr assigned, so I can query it and set its .value easily enough. However my real aim is to effect the state of the react application, that is to say, to use the text area's bound onChange handler to get my string into the state of the component which renders the text area.

So far I have tried to First: Set the value of the <textarea>. Second: trigger a "change" event. But so far this does not fire the onChange callback.

To give you an idea of what I am actually talking about I created a minimal example of this challenge.

Here's the code from that stackblitz:

The react part. This represents the react app that I have no control over.

import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends Component {

  constructor(props){
    super(props)

    this.state = {
      message: "" //I would like this be the value of what I place into the text area
    }
  }

  changeHandler = e => {
    this.setState({
      message: e.target.value
    }, ()=>{ console.log(this.state) })
  }

  render() {
    return (
      <div className="App">
        <textarea 
          id="text-area-in-react" 
          onChange={this.changeHandler}/>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

And then the non-react or external part. In this case placed in a <script> tag in index.html

<div id="root"></div>
<script>
  setTimeout(()=>{
    const textarea = document.querySelector('#text-area-in-react') 
    if(textarea){
      textarea.value = "This should be in state"

      const simChangeEvent = new Event('change', { 'bubbles': true });
      textarea.dispatchEvent(simChangeEvent);

     //when this runs I expect the react app to console.log the state, but it does not
    }
  }, 2000)
</script>

Any insights into this would be appreciated. Hopefully one or more of you out there will appreciate a crazy, hacky challenge.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
WillD
  • 5,170
  • 6
  • 27
  • 56

1 Answers1

17

After playing around with your example, I made it work with this code:

const textarea = document.querySelector('#text-area-in-react')

var nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
nativeTextAreaValueSetter.call(textarea, 'This should be in state');

const event = new Event('input', { bubbles: true});
textarea.dispatchEvent(event);

This answer helped a lot: What is the best way to trigger onchange event in react js

David
  • 743
  • 4
  • 7