You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. 安装依赖:
npm install react-native-paypal --save
# 或使用yarn
yarn add react-native-paypal
  1. 按照库文档配置安卓端权限和依赖(如添加PayPal SDK到安卓项目)
  2. 重构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支付页面:

  1. 安装依赖:
npm install react-native-webview --save
  1. 重构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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 13:59:57