ton-connect / sdk

SDK for TON Connect 2.0 — a comprehensive communication protocol between wallets and apps in TON ecosystem
Apache License 2.0
261 stars 69 forks source link

[UI-REACT]: usage with `preact` leads to `cannot read properties of undefined` of `ReactSharedInternals.ReactCurrentOwner.current` #247

Open T-Damer opened 2 weeks ago

T-Damer commented 2 weeks ago

Describe the bug

I just created a preact project and used the @tonconnect/ui-react:

import { TonConnectButton, TonConnectUIProvider } from '@tonconnect/ui-react'

export default function () {
  return (
    <TonConnectUIProvider
      manifestUrl="tonconnect-manifest.json"
    >
      <TonConnectButton />
    </TonConnectUIProvider>
  )
}

It leads to:

@tonconnect_ui-react.js?v=77482234:18856 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'current')

I inspected the source and found full the cause, it looks like this:

function jsxDEV(type, config, maybeKey, source, self2) {
  ...
  return ReactElement(type, key, ref, self2, source, ReactCurrentOwner.current, props); // error here
}

ReactCurrentOwner.current - causes the issue, it's created like:

var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;

Expected behavior

preact works fine with many react specific libraries, can we have a support for it? My project is written using preact, instead of plain react, can't spend time rewriting everything to enable the library

Current behavior

I have an error when I use the TonConnectUIProvider wrapper:

@tonconnect_ui-react.js?v=77482234:18856 Uncaught (in promise) 
TypeError: Cannot read properties of undefined (reading 'current')

Steps to Reproduce

  1. Just check my preproduction: https://codesandbox.io/p/sandbox/ton-preact-error-demo-5jqv8g

Environment

└─┬ @tonconnect/ui-react@2.0.9
  └─┬ @tonconnect/ui@2.0.9
    └─┬ @tonconnect/sdk@3.0.5
      ├── @tonconnect/isomorphic-eventsource@0.0.2
      ├── @tonconnect/isomorphic-fetch@0.0.3
      └── @tonconnect/protocol@2.2.6

Additional context

In my app I also wrap everything into SDKProvider from '@telegram-apps/sdk-react', but it doesn't affect the error, I also tried fixing by aliasing in vite.config.ts:

export default defineConfig({
  plugins: [preact()],
  resolve: {
    alias: {
      'react': 'preact/compat',
      'react-dom/test-utils': 'preact/test-utils',
      'react-dom': 'preact/compat',
      'react/jsx-runtime': 'preact/jsx-runtime'
    }
  }
});

It didn't help, also tried redefining global object:

  window.React = {
    __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
      ReactCurrentOwner: {
        current: { something: 'hello' }
      }
    }
  };

It didn't help either

T-Damer commented 2 weeks ago

Screenshot of the error from the sandbox: CleanShot 2024-08-30 at 18 36 34@2x

T-Damer commented 2 weeks ago

I see something similar over there: https://github.com/excalidraw/excalidraw/issues/5909#issuecomment-1321522731 Looks like @tonconnect/ui-react should ship it's own version of react with react internal stuff, something like this at vite.config.ts

rollupOptions: {
      external: ['react', 'react-dom', '@tonconnect/ui'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
          'react-dom/client': 'ReactDOMClient',
          'react/jsx-runtime': 'ReactJSXRuntime',
          '@tonconnect/ui': 'TON_CONNECT_UI'
        }
      }
    }

I'll try to patch and will report back

btw, that's how they fixed it: https://github.com/excalidraw/excalidraw/pull/7255

T-Damer commented 2 weeks ago

Yup, I solved it, gonna make a PR, here's a codesandbox with patched thing: https://codesandbox.io/p/sandbox/ton-preact-error-demo-forked-jpx98m?workspaceId=23a60071-d52a-4cbe-8174-4d6c2df74659