Mark Thomas Miller's logo

How to update a component's state from outside of a React app

October 16, 2019

In some circumstances, you'll want to update a component's state or access its methods from outside of a React app. This usually happens in scenarios where you're running a React app alongside an existing one — for instance, I needed to use it to safely toggle a React-based Chrome extension. Another instance might be when a large application slowly replaces its existing framework with React and still needs the app's parts to talk amongst themselves.

Luckily, React provides us with a way to handle cases like this. It's called ref. This is how to update a component's state from outside of a React app:

  1. Let's imagine that we have a component called Foobar, and we want to update its state from somewhere outside of React:

    // Foobar.jsx
    class Foobar extends Component {
      this.state = {
        updateMe: "..."
      }
    
      render() {
        return <div />
      }
    }
    
  2. Add a ref prop to Foobar where it is rendered in the parent. Inside this ref, we allow Foobar to be referenced from the window object.

    // App.jsx
    const App = () =>
      <div>
        <Foobar ref={Foobar => { window.Foobar = Foobar }} />
      </div>
    
  3. Now you can access Foobar's state and methods from outside your React app:

    // Somewhere outside the React app
    Foobar.setState({ updateMe: "Okay I'm updating you!" })
    
  4. Just remember that the component has to be rendered in order to access its state and methods. So if you have your app set up like this...

    class App extends Component {
      this.state = {
        open: false
      }
    
      render() {
        if (!open) return false
        return <Foobar ref={Foobar => { window.Foobar = Foobar }} />
      }
    }
    

    ...then App's state.open will need to be set to true before you can access Foobar outside the React app.

Of course, your actual implementation may vary. You can change window.Foobar in Step 2 to something else – like window.MyCustomName or myCustomObject.Foobar in order to fit your needs. I just wanted to make my example as simple as possible because refs can be a bit confusing.