React Native安卓端div组件配置错误,Web端正常求助
React Native安卓端出现Invariant Violation错误,Web端正常
错误提示:
ERROR Invariant Violation: 组件div的视图配置 getter 回调必须是函数(收到undefined)。请确保组件名称以大写字母开头。
代码在Web环境运行正常,但安卓应用中反复弹出上述错误,怀疑问题出在以下代码片段:
function Product1() { return ( <PayPalScriptProvider options={"client-id": "test"}> <PayPalButtons style={{ layout: "horizontal" }} /> </PayPalScriptProvider> ); }
完整项目代码
import React, { useEffect } from 'react'; import { Button, View, Text, Image, StyleSheet, ImageBackground, TouchableOpacity, ScrollView, Alert} from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { PayPalScriptProvider, PayPalButtons } from "@paypal/react-paypal-js"; function Profile() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <ImageBackground source={require('./4.png')} style={styles.image}> </ImageBackground> </View> ); } function EmptyScreen() { return ( <View style={styles.container}> <Image source={require('./3.png')} style={styles.topLeftImage} /> <View style={styles.box}> <Image source={require('./1.png')} style={styles.image} resizeMode="contain"/> <Text style={styles.description}>Box 1</Text> </View> <View style={styles.box}> <Image source={require('./2.png')} style={styles.image} resizeMode="contain" /> <Text style={styles.description}>Box 2</Text> </View> </View> ) } function Product1() { return ( <PayPalScriptProvider options={"client-id": "test"}> <PayPalButtons style={{ layout: "horizontal" }} /> </PayPalScriptProvider> ); } function Product({ navigation }){ return( <ScrollView style={{ flex: 1 }}> <View style={styles.con}> <View style={styles.box1}> <Image source={require('./2.png')} style={styles.image} resizeMode="contain" /> <View style={styles.box3}> <Text style={styles.description2}>RM 100</Text> </View> <Text style={styles.description1}>Product Name</Text> <TouchableOpacity style={styles.button} onPress={() => navigation.push('Product1')}> <Text style={styles.buttonText}>Check Now</Text> </TouchableOpacity> </View> <View style={styles.box1}> <Image source={require('./1.png')} style={styles.image} resizeMode="contain" /> <View style={styles.box3}> <Text style={styles.description2}>RM 500</Text> </View> <Text style={styles.description1}>Product Name</Text> <TouchableOpacity style={styles.button} onPress={() => navigation.push('Product1')}> <Text style={styles.buttonText}>Check Now</Text> </TouchableOpacity> </View> <View style={styles.box1}> <Image source={require('./2.png')} style={styles.image} resizeMode="contain" /> <View style={styles.box3}> <Text style={styles.description2}>RM 100</Text> </View> <Text style={styles.description1}>Product Name</Text> <TouchableOpacity style={styles.button} onPress={() => navigation.push('Product1')}> <Text style={styles.buttonText}>Check Now</Text> </TouchableOpacity> </View> </View> </ScrollView> ) } const Tab = createBottomTabNavigator(); const Stack = createNativeStackNavigator(); function Home() { return ( <Tab.Navigator> <Tab.Screen name="Main Page" component={Profile} /> <Tab.Screen name="Hari Raya" component={EmptyScreen} /> <Tab.Screen name="Products" component={Product} /> </Tab.Navigator> ); } function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Nagamotorspot" component={Home} options={{ headerRight: () => ( <Button onPress={() => alert('This is a button!')} title="Info" color="#00cc00" /> ), }} /> <Stack.Screen name="EditPost" component={EmptyScreen} /> <Stack.Screen name="Products" component={Product} /> <Stack.Screen name="Product1" component={Product1} /> </Stack.Navigator> </NavigationContainer> ); } const styles = StyleSheet.create({ lol: { flex: 1, resizeMode: 'cover', justifyContent: 'center', }, container: { flex: 1, backgroundColor: '#000000', alignItems: 'center', justifyContent: 'center', }, con: { flex: 1, backgroundColor: '#808080', alignItems: 'center', justifyContent: 'center', }, box: { width: '80%', height: 200, overflow: 'hidden', marginVertical: 10, alignItems: 'center', justifyContent: 'center', }, box1: { width: '80%', height: 280, borderRadius: 20, overflow: 'hidden', marginVertical: 10, alignItems: 'center', justifyContent: 'center', backgroundColor: '#000000', }, image: { flex: 1, width: '100%', height: '100%', resizeMode: 'cover', }, description: { position: 'absolute', bottom: 0, left: 0, right: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', color: '#fff', paddingVertical: 10, paddingHorizontal: 20, textAlign: 'center', fontWeight: 'bold', }, topLeftImage: { position: 'absolute', top: 0, alignItems: 'center', justifyContent: 'center', width: 100, height: 100, resizeMode: 'contain', }, button: { marginTop: 10, paddingVertical: 8, paddingHorizontal: 16, backgroundColor: '#00cc00', borderRadius: 8, width: '100%', alignItems: 'center', marginTop: 10, }, buttonText: { color: '#fff', fontWeight: 'bold', textAlign: 'center', }, buttonBox: { backgroundColor: '#00cc00', borderRadius: 20, paddingHorizontal: 40, paddingVertical: 10, }, description1: { position: 'absolute', bottom: 40, left: 0, right: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', color: '#fff', paddingVertical: 10, paddingHorizontal: 20, textAlign: 'center', fontWeight: 'bold', }, description2: { position: 'absolute', bottom: -10, left: 19, color: '#fff', paddingVertical: 10, paddingHorizontal: 20, fontWeight: 'bold', }, box3: { backgroundColor: "#FF6961", width: '30%', height: 40, borderRadius: 20, bottom: 200, left: -120, } }); export default App;
问题原因
@paypal/react-paypal-js是专为Web环境设计的PayPal集成库,它会渲染HTML原生标签(比如div),但React Native中不存在这些Web原生组件,因此安卓端运行时会抛出找不到div组件的错误;而Web环境可以正常解析这些标签,所以Web端运行正常。
解决方案
方案1:使用React Native专用的PayPal库
替换为React Native生态的PayPal支付库,比如react-native-paypal:
- 安装依赖:
npm install react-native-paypal --save # 或使用yarn yarn add react-native-paypal
- 按照库文档配置安卓端权限和依赖(如添加PayPal SDK到安卓项目)
- 重构
Product1组件:
import { PayPal, PayPalPayment, PayPalConfiguration } from 'react-native-paypal'; function Product1() { const handlePayment = async () => { try { const config = new PayPalConfiguration({ clientId: 'test', acceptCreditCards: true, environment: PayPalConfiguration.SANDBOX_ENVIRONMENT // 生产环境用PRODUCTION_ENVIRONMENT }); const payment = new PayPalPayment( '10.00', 'MYR', 'Product Name', PayPalPayment.PAYMENT_INTENT_SALE ); const result = await PayPal.renderSinglePaymentUI(config, payment); // 处理支付结果 console.log('Payment result:', result); } catch (error) { console.error('Payment error:', error); } }; return ( <View style={{flex:1, alignItems:'center', justifyContent:'center'}}> <Button title="Pay with PayPal" onPress={handlePayment} /> </View> ); }
方案2:用WebView包裹PayPal Web组件
如果不想更换库,可以用react-native-webview加载PayPal的Web支付页面:
- 安装依赖:
npm install react-native-webview --save
- 重构
Product1组件:
import { WebView } from 'react-native-webview'; function Product1() { const paypalHtml = ` <!DOCTYPE html> <html> <head> <script src="https://www.paypal.com/sdk/js?client-id=test"></script> </head> <body> <div id="paypal-button-container"></div> <script> paypal.Buttons({ style: { layout: 'horizontal' }, createOrder: (data, actions) => { return actions.order.create({ purchase_units: [{ amount: { value: '10.00' } }] }); }, onApprove: (data, actions) => { return actions.order.capture().then((details) => { window.ReactNativeWebView.postMessage(JSON.stringify(details)); }); } }).render('#paypal-button-container'); </script> </body> </html> `; const handleMessage = (event) => { const paymentDetails = JSON.parse(event.nativeEvent.data); // 处理支付成功后的逻辑 console.log('Payment approved:', paymentDetails); }; return ( <WebView source={{ html: paypalHtml }} onMessage={handleMessage} style={{ flex: 1 }} /> ); }
内容的提问来源于stack exchange,提问作者WALTERB PIKA
相关产品推荐
相关产品推荐

