Search code examples
javascriptreactjsreact-dom

How to communicate ReactDOM.render with other ReactDOM.render


I have a project that includes React applications and other HTML elements. It means:

ReactDOM.render(<Element1/>, document.getElementById('element1') <some section with HTML /> ReactDOM.render(<Element2/>, document.getElementById('element2')

The problem is to pass a variable/props/state from one ReactDOM.render to the other.

How can I do this?

I am currently using the global variable window, but after changing it does not refresh the data in the second ReactDOM.render.


Solution

  • In order for two React components to efficiently communicate by means of React alone, they should communicate through common parent.

    In case of two unrelated widgets, they can be rendered as portals with a common parent, as suggested in this answer:

    <div id="App"></div>
    <h2>Foo widget</h2>
    <div id="FooWidget"></div>
    <h2>Bar widget</h2>
    <div id="BarWidget"></div>
    

    class App extends Component {
      render() {
        state = {
          foo: 'foo',
          setFoo(foo) {
            this.setState(state => ({...state, foo}));
          }
        };
    
        return <FoobarContext.Provider value={this.state}>    
          {ReactDOM.createPortal(<FooWidget />, document.getElementById('FooWidget'))} 
          {ReactDOM.createPortal(<BarWidget />, document.getElementById('BarWidget'))} 
        </FoobarContext.Provider>;
      }
    }
    
    const FooWidget = props => <FoobarContext.Consumer>
      {({ foo }) => foo}
    </FoobarContext.Consumer>;
    
    ...
    
    ReactDOM.render(<App />, document.getElementById('App'));
    

    Components can communicate through foo context property by using setFoo setter.

    An alternative that can make use of ReactDOM.render is to use Redux and connect two unrelated components to same store. They can communicate through common store.