Home > front end >  What is the best way to solve the problem of sending mutations from multiple browser tabs in RTK Que
What is the best way to solve the problem of sending mutations from multiple browser tabs in RTK Que

Time:01-22

I have a simple React application that allows performing CRUD operations on various entities. It uses RTK Query to interact with the backend, and I want to utilize its built-in caching system - invalidating the cache only when a mutation is performed on an endpoint with the given tag. It works fine as long as I have only one tab open. If there are multiple users interacting with the application and one of them performs a mutation, the cache will be invalidated only in this user's browser tab. The update will not be populated to other browsers or tabs that are currently connected to the app. Each user would have to manually refresh the page after another user performed a mutation. One way to solve that is to invalidate the cache periodically, which isn't ideal, another is to force every query to re-fetch on focus, which is even worse. The best scenario would be to somehow detect that another user had sent a mutation for the given endpoint, and then invalidate the cache of this endpoint (by tags) in every other browser tab that is connected to the application. I'm looking for a solution that is better than what I've already implemented, which is the following:

  1. There's a global component with a single websocket, which immediately connects to the backend
  2. The backend assigns a unique identifier to the socket, saves it in a socket pool and sends back an event with the identifier
  3. The component with the socket saves the identifier in Redux
  4. RTK Query adds the identifier as a custom header to every request sent to the backend
  5. The backend checks the HTTP method of the request. If it is a mutation (POST / PUT / PATCH / DELETE), it extracts the identifier from the custom header, filters the socket pool excluding the socket that has the same identifier as in the request, sends an event with the tag of the service that is being mutated to all the filtered sockets
  6. The component's socket receives the event and uses RTK Query's invalidateTags utility function to invalidate the cache of the mutated service

Thanks to that, the whole app functions as if it was a real-time collaboration tool, where every change made by any user is immediately reflected in all the connected browser tabs. However, I think it is a bit too complicated and I feel like I'm reinventing the wheel. This scenario is surely quite popular, and there must be something that I'm missing, like an npm package that solves this problem, an RTK Query option that I've omitted, or a well-known design pattern. Of course, there are multiple packages that allow synchronizing Redux Store across multiple tabs, but that doesn't solve the problem of having multiple users connecting from different devices.

CodePudding user response:

It works fine as long as I have only one tab open

JS code lives within a single tab / open page by default.

That includes JS variables and logic, and the Redux store is just another JS variable.

RTK Query is not specifically designed to interact across tabs. You'll have to write that part yourself.

If the concern is multiple users interacting with the same backend server, that's what RTK Query's polling options are for. Alternately, yeah, you could have the server send a signal via websocket to let the client know it needs to refetch data. But again, that's something you'll need to write yourself, as it's specific to the needs of your own application.

  • Related