gqty icon indicating copy to clipboard operation
gqty copied to clipboard

no component rerender on React Native Hermes engine with disabled suspense and useQuery

Open Nlcke opened this issue 3 years ago • 6 comments

Hello and thanks for great library! We are using useQuery hook in React Native framework with Hermes engine and suspense: false option.

"gqty": "2.3.0"
"@gqty/react": "3.0.0-alpha-74109b4.0" (suspense: false)
"react": "18.1.0"
"react-native": "0.70.2" (Hermes engine enabled)
OS: Android

When using V8 engine (enabled in debug mode) everything is fine, however something is wrong with useQuery on Hermes engine. Components do not rerender when receiving server response. We are found useDeferDispatch function doesn't work properly inside @gqty/react/common.js maybe due to some effects/promises/timeouts race.

As a workaround we are currently using patch-package with following patch, it works fine for our requests: @gqty+react+3.0.0-alpha-74109b4.0.patch

diff --git a/node_modules/@gqty/react/common.js b/node_modules/@gqty/react/common.js
index 5d70f2b..0529ad0 100644
--- a/node_modules/@gqty/react/common.js
+++ b/node_modules/@gqty/react/common.js
@@ -90,13 +90,22 @@ function useDeferDispatch(dispatchFn) {
           if (isMounted.current)
             dispatchFn(...args);
         });
+      } else {
+        pendingDispatch.current = [
+          () => {
+            if (isMounted.current)
+              dispatchFn(...args);
+          }
+        ];
       }
-      pendingDispatch.current = [
-        () => {
-          if (isMounted.current)
-            dispatchFn(...args);
+      Promise.resolve().then(() => {
+        if (pendingDispatch.current) {
+          for (const fn of pendingDispatch.current) {
+            fn();
+          }
+          pendingDispatch.current = false;
         }
-      ];
+      });
     } else if (isMounted.current) {
       dispatchFn(...args);
     }

Please help to make it work properly on Hermes engine.

Nlcke avatar Oct 18 '22 13:10 Nlcke

Whats the status on this @vicary ? We're facing similar issues on the useTransactionQuery. It works when replacing

const dispatch = useDeferDispatch(dispatchReducer);

with

const dispatch = dispatchReducer;

https://user-images.githubusercontent.com/4349324/220602488-b089a2fb-34ae-406c-91ca-3761ef2bb45e.mov

bkniffler avatar Feb 22 '23 11:02 bkniffler

@bkniffler Hermes needs it's own care, especially when paired with concurrency mode and suspense.

When I start working on this one I'll crunch through all the workarounds and make it stable.

vicary avatar Feb 22 '23 11:02 vicary

Sorry for not being clear, its not about hermes in my case, its about the useDeferDispatch hook in general (on web in my case). @vicary

bkniffler avatar Feb 22 '23 11:02 bkniffler

@bkniffler Is it only happening in response to user interactions? Please help me reproduce this by updating this one https://stackblitz.com/edit/nextjs-nzmtym?file=pages/index.tsx

vicary avatar Feb 22 '23 14:02 vicary

I've tried to reproduce it, but unfortunately couldn't. Would have to dig deeper into this, but its surely an issue with the dispatch.

bkniffler avatar Feb 22 '23 23:02 bkniffler

Please take your time, depends on the result I may move it to a separate issue for easier tracking.

vicary avatar Feb 23 '23 06:02 vicary