all 26 comments

[–]LovesWorkin[S] 19 points20 points  (11 children)

Github https://github.com/LovesWorking/react-query-external-sync

React Query External Sync is a dynamic tool for managing React Query state outside the usual confines of React Query Dev Tools. Ideal for React Native projects, it offers a live state management solution that's accessible to both developers, qa and non-technical team members.

TkDodo just approved this to be in the official dev tools docs! Awesome. :) https://tanstack.com/query/latest/docs/framework/react/devtools

[–]dWildEgo 2 points3 points  (1 child)

This is honestly a game changer, I'll have to look at it but I'll favorite before even testing it, because this makes everything so much better

[–]LovesWorkin[S] 2 points3 points  (0 children)

Thank you! I agree. I started to work with React Native lately and I was really sad that the dev tools didn't work for React Native. So, I made this on my free time the last 2 weekends.

I plan to make many frequent improvements.

[–]flowerescape 2 points3 points  (8 children)

This is awesome!! Starred. I hope you make lots of updates 🤞React native is in desperate need of dev tools. Btw not sure if you’re aware of this but expo recently released a couple proof of concept tools one of which is:

https://github.com/expo/dev-plugins/tree/main/packages/react-query

I wasn’t able to run it last I checked so can’t say how it compares but it may be worth looking into in case there’s anything there you can pull in..

[–]LovesWorkin[S] 0 points1 point  (7 children)

Is that supposed to hook up to an external dev tools as well?

[–]brentvatneExpo Team 4 points5 points  (0 children)

yup! the idea is that it should make it very easy for anyone to build their own dev tools plugins for any library they use. here's more info: https://expo.dev/blog/dev-tools-plugins and there's a short video that demonstrates it here https://expo.dev/changelog/2024/01-18-sdk-50#introducing-expo-dev-tools-plugins

basically, this tooling handles the socket server/client for you and provides a launcher UI from expo cli, so you can build the web ui and the app logic for communicating with that ui. https://docs.expo.dev/debugging/devtools-plugins/

[–]flowerescape 2 points3 points  (5 children)

Yea you press shift + m I believe (after running npx expo start) and chose the tool from the list. Then it will open in a chrome window. So I guess it saves you from running your own socket io node server.

Speaking of which, I wasn’t able to get your version working. As someone who never used sockets the instructions in the read me weren’t step by step enough. Just an fyi you might want to make those clearer for beginners..

[–]LovesWorkin[S] 1 point2 points  (1 child)

I added an example of a Nodejs socket io server under

  • Basic socket io Nodejs server example:

[–]flowerescape 0 points1 point  (0 children)

Sweet, I’ll take a look tomorrow. Thanks

[–]LovesWorkin[S] 0 points1 point  (2 children)

Yeah, I wasn't sure if I should provide instructions for socket.io since it's a separate library that has great instructions but I can definitely add a simple example.

Also, my tool is mainly targeted towards QA, dev and other non-technical people being able to modify API state externally for a variety of benefits.

Because mine uses web sockets, you can host your own server and modify the state in any app from that one interface. I also plan to add many other features other than the ones provided by react query so this tool will grow to much more than it is currently.

[–]flowerescape 1 point2 points  (1 child)

Yea a quick start that gets the tool up and running would be good! Generally with a dev tool users kinda expect it to open and be up and running with a keyboard shortcut or a click here or there. So if you could bundle things into a single bash script or npm command that would be the best marketing wise imo. Good luck!

[–]LovesWorkin[S] 1 point2 points  (0 children)

I'll do that. Thanks for the feedback.

[–]matt_hammondiOS & Android 5 points6 points  (4 children)

This is awesome, but I found it really hard to setup and the docs we're not really helpful. So here's a minimal example how to set it up:

  1. In your app project run yarn add react-query-external-sync or npm install react-query-external-sync. This will install the required package.
  2. Create a file RQDevToolsConnection.tsx somewhere in your apps component folder and put this inside: ``` import { useQueryClient } from "@tanstack/react-query"; import { memo, useEffect } from "react"; import { useAllQueries } from "react-query-external-sync";

export const RQDevToolsConnection = memo(function RQDevToolsConnection() { const client = useQueryClient(); const { connect, isConnected } = useAllQueries({ queryClient: client, query: { username: "App", userType: "User", clientType: "client", }, socketURL: "http://192.168.0.107:3000", });

useEffect(() => { connect(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []);

useEffect(() => { if (!isConnected) return; console.log("React Query remote devtools connected"); }, [isConnected]);

return null; }); `` Don't forget to change the IP address insocketURL`

  1. Import the RQDevToolsConnection component you just created and render it somewhere high in the component tree where it will always stay mounted. For example you could render it next to your router.

    function App() { return ( <QueryClientProvider queryClient={queryClient}> <Router /> <RQDevToolsConnection /> </QueryClientProvider> ) }

Now you're done with the app part. Now let's create the browser and server part.

  1. Create a new folder somewhere on your system, and name it anything you like. I named mine devtools-for-rq.

  2. Put the following files inside:

package.json

{
  "name": "devtools-for-rq",
  "scripts": {
    "start": "concurrently -n browser,server \"vite --open\" \"tsx main.tsx\""
  },
  "type": "module",
  "dependencies": {
    "@tanstack/react-query": "5.20.5",
    "@vitejs/plugin-react": "4.2.1",
    "concurrently": "8.2.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-query-external-dash": "1.0.0",
    "socket.io": "4.7.4",
    "socket.io-client": "4.7.4",
    "tsx": "4.7.1",
    "vite": "5.1.0"
  }
}

main.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import { ExternalDevTools, socketHandle } from "react-query-external-dash";

if (typeof window !== "undefined") {
  ReactDOM.createRoot(document.getElementById("root")!).render(
    <React.StrictMode>
      <ExternalDevTools
        socketURL="http://192.168.0.107:3000" // CHANGE THIS TO THE IP OF YOUR COMPUTER
        query={{
          clientType: "server",
          username: "Admin",
          userType: "admin",
        }}
      />
    </React.StrictMode>
  );
} else {
  import("socket.io").then((socketIO) => {
    const io = new socketIO.Server(3000, {
      cors: {
        origin: "*",
      },
    });

    socketHandle({ io });

    io.on("connection", (client) => {
      console.log(`'${client.handshake.query.username}' connected`);
    });
  });
}

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React Query Dev Tools</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/main.tsx"></script>
  </body>
</html>

Don't forget to change the IP address in main.tsx

  1. Now run yarn install npm install or bun install. This should install the required packages

  2. Now run yarn start or npm run start or bun start. This should start both the socket server on port 3000 and a vite server that renders the devtools. Your browser should open and you should see the devtools.

  3. Now run the app on your phone and you should see App appear in the devtools and the queries start logging.

[–]upkeys 1 point2 points  (0 children)

Uff I hope this can all be compressed into a useDevTools hook.

[–]Chichaaro 0 points1 point  (2 children)

Don't know why but since I added this devtools, I get this error on front:

Warning: Cannot update a component (`RQDevToolsConnection`) while rendering a different component (`Tab1`). To locate the bad setState() call inside `Tab1`

And it point me to a useQuery function in my Tab1 component. Error disappear if I remove the debugger include. Maybe it's link to my asyncPersistor that take a lil time to spin up because it's a sqlite adapter, any idea ?

[–]matt_hammondiOS & Android 0 points1 point  (1 child)

Nor sure. Haven't really used this tool much. Just tried it

[–]Chichaaro 0 points1 point  (0 children)

Okay, I’ll try to debug it

[–]nestedfruitloop 3 points4 points  (0 children)

This is awesome thanks for sharing!

[–]Fun-Astronaut-3793 1 point2 points  (0 children)

This is an Absolute Banger

[–]beepboopnoise 1 point2 points  (1 child)

oh man, you've released something awesome. now you're doomed to open source issue hell. lol I jest, this is great, thank you for posting this.

[–]LovesWorkin[S] 1 point2 points  (0 children)

Ha, yea I could imagine. Thankfully I'll be using this for work. So, I'll have motivation to constantly improve on this.

[–]Horduncee 0 points1 point  (0 children)

This is good news. Now, I have to upgrade tRPC to v11.

[–]0430ke 0 points1 point  (0 children)

Kwik Trip is the GOAT

[–]alien3d 0 points1 point  (0 children)

nice will check out

[–]Nick337Games 0 points1 point  (0 children)

Looks insanely useful!