Home > other >  How to manage active communication between two independent react apps?
How to manage active communication between two independent react apps?

Time:09-28

I have a react app that needs to render into two different DOM root elements. What is the best way that I can share data between them based on changes inside one of them? It seems like I cannot wrap two apps in a context provider or use a state/effect/callback way to have communication between them.

ReactDOM.render(
      <ReactApp1 componentData={}/>
      , rootElement1
); 
ReactDOM.render(
      <ReactApp2 componentData={}/>
      , rootElement2 
);

CodePudding user response:

If the only reason you're splitting things up is because you need to put content into two unrelated dom nodes, you may be able to achieve this with a portal instead of two calls to ReactDOM.render. That way, you can use standard props and/or context to pass things between your components.

ReactDOM.render(
  <App />
  rootElement1
)

const App = () => {
  const rootElement2 = /* some code to select rootElement2 from the page. eg, document.getElementById('someId') */

  return (
    <>
      <ReactApp1 componentData={/*...*/}/>
      {React.createPortal(<ReactApp2 componentData={/*...*/} />, rootElement2)}
    </>

  )
}

If that's not possible and you need completely separate calls to ReactDOM.render, then most likely you will need to create some pub/sub code and have the apps send messages to eachother. If you have a favorite library for event emitters you can use that, or if you want to create your own it might look something like this:

// These lines will probably be in their own file
const subscriptions = [];
export const subscribe = (callback) => {
  subscriptions.push(callback);
  const unsubscribe = () => {
    const i = subscriptions.findIndex(callback);
    subscriptions.splice(i, 1);
  }
  return unsubscribe
}
export const publish = (data) => {
  [...subscriptions].forEach(callback => callback(data));
}

// Used like:

const ReactApp1 = () => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    // Listen to messages
    const unsubscribe = subscribe((data) => {
      setCount(data);
    });
    return unsubscribe;
  }, []);

  return <div onClick={() => {
    publish(count   1);
  }}/>
}
  • Related