inokawa / react-native-react-bridge

An easy way to integrate your React (or Preact/React Native Web) app into React Native app with WebView.
https://www.npmjs.com/package/react-native-react-bridge
MIT License
270 stars 21 forks source link

Property 'document' doesn't exist #188

Open zekoliman opened 4 months ago

zekoliman commented 4 months ago

Platform:

pedrozok commented 4 months ago

I have the same issue, @zekoliman did you found a solution for it?

zekoliman commented 4 months ago

@pedrozok I spent two days but unfortunately I couldn't find a solution.

lukachi commented 4 months ago

same here, any solutions yet?

UPD:

Environment: default expo app with expo-router new-architecture

pck versions:

    "react-native-react-bridge": "^0.12.0",
    "react-native-web": "^0.19.12",
    "react-native-webview": "^13.10.5",

provider:

import type { PropsWithChildren } from 'react'
import { useContext } from 'react'
import { createContext } from 'react'
import { useWebViewMessage } from 'react-native-react-bridge'
import { WebView } from 'react-native-webview'

import { ErrorHandler } from '@/core'

import { WitnessRequestTypes, WitnessResponseTypes } from './enums'
import WebApp from './WebApp'

const witnessCalcContext = createContext<{
  executeWitnessCalculator: <Inputs>(binary: Uint8Array, inputs: Inputs) => Promise<string>
}>({
  executeWitnessCalculator: async () => {
    throw new TypeError('not implemented')
  },
})

export const useWitnessCalc = () => {
  return useContext(witnessCalcContext)
}

export const WitnessCalcProvider = ({ children }: PropsWithChildren) => {
  let promiseResolver: any

  const { ref, onMessage, emit } = useWebViewMessage(message => {
    if (message.type === WitnessResponseTypes.WitnessCalculatorResponse) {
      promiseResolver(message.data)
    }
  })

  async function executeWitnessCalculator<Inputs>(
    binary: Uint8Array,
    inputs: Inputs,
  ): Promise<string> {
    emit({
      type: WitnessRequestTypes.WitnessCalculatorRequest,
      data: {
        binary,
        inputs,
      },
    })

    return new Promise(resolve => {
      promiseResolver = resolve
    })
  }

  return (
    <witnessCalcContext.Provider
      value={{
        executeWitnessCalculator,
      }}
    >
      <WebView
        ref={ref}
        source={{ html: WebApp }}
        onMessage={onMessage}
        onError={ErrorHandler.process}
      />
      {children}
    </witnessCalcContext.Provider>
  )
}

the provider itself wrapped nested router, NOT the whole app, but in this case it ain't works too

- root
- - subroute
- - - sub_subroute <- here

WebApp.tsx

import { emit, useNativeMessage, webViewRender } from 'react-native-react-bridge/lib/web'

import { WitnessRequestTypes, WitnessResponseTypes } from '@/utils/zkp/enums'

function WebApp() {
  useNativeMessage(message => {
    if (message.type === WitnessRequestTypes.WitnessCalculatorRequest) {
      emit({
        type: WitnessResponseTypes.WitnessCalculatorResponse,
        data: message.data,
      })
    }
  })

  return <></>
}

export default webViewRender(<WebApp />)

UPD:

I was able to avoid this error by replace in source like so:

source={{
  html: `
    <html>
          <head>
            <meta name="viewport" content="width=device-width, initial-scale=1" />
          </head>
          <body>
            <h1>Silver area is a WebView</h1>
          </body>
    </html>
  `,
}}

and also run simple scripts with:

injectedJavaScript={myScript} // string

but anyway, the post messages ain't works with this example:

window.addEventListener('message', async (message) => {
// do my stuff
})

and, i think, that kind of flow is roughly limits most of real case projects

YadBro commented 1 month ago

+1