Q: Redux communication between browser tabs makes ping-pong effect (multiway communication) I saw a lot of solutions on how to communicate/share data between tabs with Redux/JavaScript with localstorage. Like:
import { applyMiddleware, createStore } from "redux";
import logger from "redux-logger";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";

import reducer from "./reducers";
import {sourceId} from "./utils/helper";

const storageKey = 'redux-local-tab-sync';

function wrapAction(action) {
  return {
    action,
    sourceId,
    time: Date.now()
  }
}

function storageMiddleware() {
  return () => next => action => {
    const wrappedAction = wrapAction(action);

    localStorage.setItem(storageKey, JSON.stringify(wrappedAction));

    next(action);
  }
}

export function createStorageListener(store) {
  return () => {
    const wrappedAction = JSON.parse(localStorage.getItem(storageKey));

    if (wrappedAction.sourceId !== sourceId) {
      console.log(wrappedAction.action)
      store.dispatch(wrappedAction.action);
    }
  }
}

const middleware = applyMiddleware(promise(), thunk, storageMiddleware(), logger());
const store = createStore(reducer, middleware);

window.addEventListener('storage', createStorageListener(store));

export default store;

or Javascript: sharing data between tabs and Communication between tabs or windows .
However all of the solutions which I found have a little problem. They create a ping-pong effect. So when A tab storage changes, then B tab storage will be set, because it gets a message from localstorage. However, because B tab storage was change, it's fires the 'same change event' (but with own information), which was previously sent by A tab. So A tab's storage will be change via local storage event... and everything starts from the beginning.
Is there a better way to handle the syncing of information where:
- A can send message to B [, C, D, ...]; B can send a message to A [, C, D, ...]; etc
- without making ping-pong effect,
- prevent to infinitely change own's storage.

A: Maybe the following will work, it will create a special type of action when triggered from another tab:
function storageMiddleware() {
  return () => next => action => {
    if(action.type!=="from other tab"){
      const wrappedAction = wrapAction(action);
      localStorage.setItem(storageKey, JSON.stringify(wrappedAction));
    }else{
      action=action.data;
    }
    next(action);
  }
}

export function createStorageListener(store) {
  return () => {
    const wrappedAction = JSON.parse(localStorage.getItem(storageKey));

    if (wrappedAction.sourceId !== sourceId) {
      console.log(wrappedAction.action)
      store.dispatch({
        type:"from other tab",
        data:wrappedAction.action
      });
    }
  }
}


A: Maybe you can try this https://github.com/AOHUA/redux-state-sync , broadcast channel is a better way to communicate between tabs.
