Skip to content

Commit 43cf30c

Browse files
committed
Improve useWebViewMessage API
1 parent 97019a9 commit 43cf30c

File tree

6 files changed

+30
-25
lines changed

6 files changed

+30
-25
lines changed

README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -208,18 +208,19 @@ export default webViewRender(<Root />);
208208

209209
import React from "react";
210210
import WebView from "react-native-webview";
211-
import { useWebViewMessage } from "react-native-react-bridge";
211+
import { emit, useWebViewMessage } from "react-native-react-bridge";
212212
import webApp from "./WebApp";
213213

214214
const App = () => {
215+
const ref = useRef(null);
215216
// useWebViewMessage hook create props for WebView and handle communication
216217
// The argument is callback to receive message from React
217-
const { ref, onMessage, emit } = useWebViewMessage((message) => {
218+
const onMessage = useWebViewMessage((message) => {
218219
// emit sends message to React
219220
// type: event name
220221
// data: some data which will be serialized by JSON.stringify
221222
if (message.type === "hello" && message.data === 123) {
222-
emit({ type: "success", data: "succeeded!" });
223+
emit(ref, { type: "success", data: "succeeded!" });
223224
}
224225
});
225226

examples/DemoApp/App.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @flow strict-local
77
*/
88

9-
import React, {useState} from 'react';
9+
import React, {useRef, useState} from 'react';
1010
import {
1111
SafeAreaView,
1212
StyleSheet,
@@ -16,12 +16,13 @@ import {
1616
TextInput,
1717
} from 'react-native';
1818
import WebView from 'react-native-webview';
19-
import {useWebViewMessage} from 'react-native-react-bridge';
19+
import {emit, useWebViewMessage} from 'react-native-react-bridge';
2020
import webApp from './WebApp';
2121

2222
const App = () => {
2323
const [data, setData] = useState('This is React Native');
24-
const {ref, onMessage, emit} = useWebViewMessage(message => {
24+
const ref = useRef(null);
25+
const onMessage = useWebViewMessage(message => {
2526
if (message.type === 'hi') {
2627
setData(message.data);
2728
}
@@ -44,7 +45,7 @@ const App = () => {
4445
value={data}
4546
/>
4647
<Pressable
47-
onPress={() => emit({type: 'hello', data: data})}
48+
onPress={() => emit(ref, {type: 'hello', data: data})}
4849
style={styles.button}>
4950
<Text>send to Web</Text>
5051
</Pressable>

examples/DemoAppExpo/App.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @flow strict-local
77
*/
88

9-
import React, { useState } from "react";
9+
import React, { useRef, useState } from "react";
1010
import {
1111
SafeAreaView,
1212
StyleSheet,
@@ -16,12 +16,13 @@ import {
1616
TextInput,
1717
} from "react-native";
1818
import WebView from "react-native-webview";
19-
import { useWebViewMessage } from "react-native-react-bridge";
19+
import { emit, useWebViewMessage } from "react-native-react-bridge";
2020
import webApp from "./WebApp";
2121

2222
const App = () => {
2323
const [data, setData] = useState("This is React Native");
24-
const { ref, onMessage, emit } = useWebViewMessage<string>((message) => {
24+
const ref = useRef<WebView>(null);
25+
const onMessage = useWebViewMessage<string>((message) => {
2526
if (message.type === "hi") {
2627
setData(message.data);
2728
}
@@ -44,7 +45,7 @@ const App = () => {
4445
value={data}
4546
/>
4647
<Pressable
47-
onPress={() => emit({ type: "hello", data: data })}
48+
onPress={() => emit(ref, { type: "hello", data: data })}
4849
style={styles.button}
4950
>
5051
<Text>send to Web</Text>

src/native/index.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useRef } from "react";
1+
import { RefObject, useCallback } from "react";
22
import type WebView from "react-native-webview";
33
import type { WebViewMessageEvent, WebViewProps } from "react-native-webview";
44
import { TO_WEB_EVENT_KEY } from "../constants";
@@ -28,23 +28,25 @@ export const buildEmitToWebView = <T>(
2828
export const useWebViewMessage = <T>(
2929
onSubscribe: (message: WebViewMessage<T>) => void
3030
) => {
31-
const ref = useRef<WebView>(null);
32-
const onMessage: WebViewProps["onMessage"] = useCallback(
33-
(event: WebViewMessageEvent) => {
31+
return useCallback(
32+
((event: WebViewMessageEvent) => {
3433
try {
3534
const res = JSON.parse(event.nativeEvent.data);
3635
onSubscribe({ type: res.type, data: res.data });
3736
} catch (e) {
3837
// NOP
3938
}
40-
},
39+
}) satisfies WebViewProps["onMessage"],
4140
[onSubscribe]
4241
);
43-
const emit = useCallback(
44-
(message: ReactNativeMessage<T>) => {
45-
ref.current?.injectJavaScript(buildEmitToWebView(message));
46-
},
47-
[ref]
48-
);
49-
return { ref, onMessage, emit };
42+
};
43+
44+
/**
45+
* A function to send a message to WebView.
46+
*/
47+
export const emit = <T>(
48+
ref: RefObject<WebView>,
49+
message: ReactNativeMessage<T>
50+
) => {
51+
ref.current?.injectJavaScript(buildEmitToWebView(message));
5052
};

src/web/core.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const getWebViewRootElement = (): HTMLElement =>
88
document.getElementById(WEB_ROOT_ID)!;
99

1010
/**
11-
* A function to send a message to React Native
11+
* A function to send a message to React Native.
1212
*/
1313
export const emitToNative = <T>(message: WebViewMessage<T>) => {
1414
(window as any).ReactNativeWebView.postMessage(JSON.stringify(message));

src/web/react.spec.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ describe("send message to native", () => {
9898
const NativeApp = ({ target }: { target: string }) => {
9999
const [data, setData] = useState<null | string>(null);
100100
const [count, setCount] = useState(0);
101-
const { onMessage } = useWebViewMessage<string>((m) => {
101+
const onMessage = useWebViewMessage<string>((m) => {
102102
if (m.type === target) {
103103
setData(m.data);
104104
}

0 commit comments

Comments
 (0)