1import { H2 } from '@expo/html-elements'; 2import * as React from 'react'; 3import { ActivityIndicator, StyleSheet, View, ScrollView } from 'react-native'; 4import { WebView } from 'react-native-webview'; 5 6interface MessageEvent { 7 nativeEvent: { 8 data: string; 9 }; 10} 11 12const injectedJavaScript = `window.ReactNativeWebView.postMessage(JSON.stringify(window.location));`; 13 14export default function WebViewScreen() { 15 return ( 16 <ScrollView style={{ flex: 1 }} contentContainerStyle={{ flex: 1 }}> 17 <WebViewRemoteSource /> 18 <WebViewInlineSource /> 19 </ScrollView> 20 ); 21} 22 23WebViewScreen.navigationOptions = { 24 title: 'WebView', 25}; 26 27function WebViewRemoteSource() { 28 const [isLoading, setLoading] = React.useState(true); 29 30 return ( 31 <View style={styles.container}> 32 <H2 style={styles.header}>Remote Source</H2> 33 <WebView 34 source={{ uri: 'https://expo.dev/' }} 35 onLoadEnd={() => setLoading(false)} 36 onMessage={({ nativeEvent: { data } }: MessageEvent) => { 37 console.log('Got a message from WebView: ', JSON.parse(data)); 38 }} 39 injectedJavaScript={injectedJavaScript} 40 /> 41 {isLoading && <ActivityIndicator style={StyleSheet.absoluteFill} />} 42 </View> 43 ); 44} 45 46function WebViewInlineSource() { 47 return ( 48 <View style={styles.container}> 49 <H2 style={styles.header}>Inline Source</H2> 50 <WebView 51 style={{ width: '100%', height: 250 }} 52 source={{ 53 html: ` 54 <h2>You can always use a WebView if you need to!</h2> 55 <p> 56 <h4>But don't the other components above seem like better building blocks for most of your UI?</h4> 57 <input type="text" placeholder="Disagree? why?" /> 58 <input type="submit"> 59 </p> 60 <p> 61 <a href="https://expo.dev">expo.dev</a> 62 </p> 63 `, 64 }} 65 /> 66 </View> 67 ); 68} 69 70const styles = StyleSheet.create({ 71 container: { 72 flex: 1, 73 minHeight: '50%', 74 overflow: 'hidden', 75 }, 76 header: { 77 marginLeft: 8, 78 }, 79}); 80