gronxb / webview-bridge

Fully Type-Safe Integration for React Native WebView and Web
https://gronxb.github.io/webview-bridge/
MIT License
222 stars 5 forks source link

Upgrading from 1.4.1 to latest version gives errors in Next.JS #54

Closed steelzeh closed 3 months ago

steelzeh commented 3 months ago

Thank you for all the great work you are doing!

I have recently come across an issue in Next.js In version 1.4.1 everything seems to be working great, but when upgrading to the latest version I'm getting these errors

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

The result of getServerSnapshot should be cached to avoid an infinite loop

The code in particular occurs when using useBridgeStore inside a provider, here I have the LocationProvider where I use the useBridgeStore and the issues occur. These do not happen in 1.4.1

Here is a small sandbox where the issue is reproduced https://codesandbox.io/p/sandbox/bridge-error-6mqtgj

gronxb commented 3 months ago

Thank you for providing the sandbox. I will check it out soon.

nick0504k commented 3 months ago

I had a similar issue, but for a different reason. If you’re using Yarn Plug’n’Play (PnP), you might want to try setting nodeLinker: node-modules in your .yarnrc.yml file. Then, remove pnp.js and your .lock files, and run yarn install again. This might solve the problem.

steelzeh commented 3 months ago

I had a similar issue, but for a different reason. If you’re using Yarn Plug’n’Play (PnP), you might want to try setting nodeLinker: node-modules in your .yarnrc.yml file. Then, remove pnp.js and your .lock files, and run yarn install again. This might solve the problem.

Unfortunately this also happens when simply using npm

gronxb commented 3 months ago

Hey, @steelzeh

I have confirmed that the issue occurs correctly work in the React Native WebView environment, but it causes errors in non-React Native WebView environment.

Therefore, this issue has been resolved in version 1.5.3.

Here is the CodeSandbox for version 1.5.3 on the same codebase: https://codesandbox.io/p/devbox/bridge-error-forked-sfkq6w

Let me know if you need any more changes!

steelzeh commented 3 months ago

Hey, @steelzeh

I have confirmed that the issue occurs correctly work in the React Native WebView environment, but it causes errors in non-React Native WebView environment.

Therefore, this issue has been resolved in version 1.5.3.

Here is the CodeSandbox for version 1.5.3 on the same codebase: https://codesandbox.io/p/devbox/bridge-error-forked-sfkq6w

Let me know if you need any more changes!

Yes that fixes the issue thanks! Great work!

I don't know if this is related or not, but now I'm getting an error when running via react-native and when using

const { isNativeMethodAvailable } = useBridgeStatus();

IMG_8469

steelzeh commented 3 months ago

I'm also getting these errors

CleanShot 2024-07-09 at 20 44 20@2x

gronxb commented 3 months ago

This issue only occurs in the SSR environment 🫠

I think I need to create a separate field for initialState to hydrate the non-react-native state for the SSR environment.

For example, it should look something like this:

createLinkBridgeProvider<AppBridge>({
    throwOnError: true,
     // this field
     initialBridge: {
          requestLocation: () => {},
          text: "",
     },
     onReady: () => {
      console.log("bridge is ready");
    },
  });

Thank you. I will prepare it as soon as I have time.

steelzeh commented 3 months ago

Thank you for looking into this!

Wouldn't this also open up the possibility to test without having to run the react-native part, as you could mock the response?

gronxb commented 3 months ago

That’s right. It will be included in linkBridge and will be extended to createLinkBridgeProvider. Once this feature is implemented, mocking will be possible when not in a React Native environment.

Thank you for the inspiration

gronxb commented 3 months ago

@steelzeh

The issue has been resolved in version 1.6.0.

Please check again using the following link: CodeSandbox Project

By using the initialBridge field, you can mock the behavior and ensure that values are displayed correctly even when not in a React Native environment.


export const {
  BridgeProvider,
  useBridgeStore,
  useBridgeStatus,
  useBridgeLoose,
} = createLinkBridgeProvider<AppBridge>({
  throwOnError: true,
  timeout: 30000,
  // this field
  initialBridge: {
    requestLocation: async () => {
      alert("requestLocation is mocking");
      return "I'm from native";
    },
  },
  onReady: (bridge) => {
    if (!bridge.isWebViewBridgeAvailable) {
      console.log("Bridge not available");
      return;
    }
  },
});
steelzeh commented 3 months ago

Thank you so much for looking into this so quickly, you are the best!

Quick question

I have included the initialBridge, but when testing on web without react-native, isWebViewBridgeAvailable now returns true, is that because we now have the mocked bridge?

And also it seems to be throwing an error when trying to use isNativeMethodAvailable

CleanShot 2024-07-11 at 10 52 04@2x

steelzeh commented 3 months ago

@gronxb Here is the updated codesandbox with the error 😄 sandbox

gronxb commented 3 months ago

~~I have reviewed the sandbox you provided. You need to add 'use client' to the page.tsx file. After downloading the provided sandbox and adding 'use client', it worked correctly. I also recommend clearing your .next and node_modules folders to ensure everything is set up properly.~~

I'm getting the same error as the picture you posted even after adding use client. I'll check it out.

Additionally, the reason isWebViewBridgeAvailable is true is due to mocking. For more details, please refer to the release notes: https://github.com/gronxb/webview-bridge/releases/tag/v1.6.0.

If you want isWebViewBridgeAvailable to be false, I have confirmed that it works even without the initialBridge. Additionally, I have verified that it work in an SSR environment even without the initialBridge.

To check for a React Native environment, the following code snippet might be helpful:

const isReactNative = Boolean(window.ReactNativeWebView);
steelzeh commented 3 months ago

Hmm, I don't know if this only happens when used in a layout maybe, this happens both locally and on codesandbox

I have updated it here sandbox also when using "use client"

Maybe I'm misunderstanding something 😄

Navigate to /auth in the preview

gronxb commented 3 months ago

I have completed the test in the provided sandbox. Please try with version 1.6.1.

steelzeh commented 3 months ago

It works!

Thank you for doing this amazing work, I really appreciate it!