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

React Native仿Snapchat相机页面渲染错误求助

问题修复:React Native相机页面渲染错误「Element type is invalid」

错误核心原因

出现该错误的本质是你导入了不存在的组件(返回undefined),结合代码来看主要有以下几个问题:

  • 冗余且无效的导入导致变量undefined
  • NativeBase图标组件配置或名称错误
  • 未正确传递Camera组件的核心属性
  • 部分逻辑判断存在漏洞

修复后的完整代码

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import { Container, Header, Item, Icon, Input } from 'native-base';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Camera } from 'expo-camera';

export default function VideoScreen() {
  const [hasCameraPermission, sethasCameraPermission] = useState(null);
  const [camera, setCamera] = useState(null);
  const [image, setImage] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.front);

  useEffect(() => {
    (async () => {
      const cameraStatus = await Camera.requestCameraPermissionsAsync();
      sethasCameraPermission(cameraStatus.status === 'granted');
    })();
  }, []);

  const takePicture = async () => {
    if (camera) {
      const data = await camera.takePictureAsync();
      setImage(data.uri);
    }
  };

  // 权限状态分支处理
  if (hasCameraPermission === false) {
    return <Text>No Camera Access</Text>;
  }
  if (hasCameraPermission === null) {
    return <Text>Requesting Camera Permission...</Text>;
  }

  return (
    <View style={{ flex: 1 }}>
      <Camera 
        ref={ref => setCamera(ref)} 
        style={{ flex: 1, justifyContent:'space-between' }}
        type={type}
      >
        <Header
          searchBar rounded
          style={{position: 'absolute', backgroundColor: 'transparent', left:0, top: 0, right: 0, zIndex:100}}
        >
          <View style={{flexDirection:'row', flex:4}}>
            <Icon name="fire" style={{ color: 'white' }} />
            <Item style={{ backgroundColor: 'transparent' }}>
              <Icon name="ios-search" style={{color:'white',fontSize:24, fontWeight:'bold'}} />
              <Input placeholder="Search" placeholderTextColor="white"/>
            </Item>
          </View>
          <View style={{flexDirection:'row', flex:2,justifyContent:'space-around'}}>
            <Icon name="ios-flash" style={{ color: 'white', fontWeight:'bold'}} />
            <Icon
              name="ios-reverse-camera"
              style={{ color: 'white', fontWeight: 'bold' }}
              onPress={() => {
                setType(type === Camera.Constants.Type.front ? Camera.Constants.Type.back : Camera.Constants.Type.front);
              }} 
            />
          </View>
        </Header>
        <View style={{ flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 10, marginBottom: 15,alignItems:'flex-end'}} >
          <MaterialCommunityIcons name="message-reply" style={{ color: 'white', fontSize: 36 }} />
          <View style={{ alignItems: 'center' }}>
            <MaterialCommunityIcons 
              name="circle-outline"
              style={{ color: 'white', fontSize: 100 }}
              onPress={takePicture}
            />
            {image && <Image source={{uri:image}} style={{width: 80, height: 80, position: 'absolute', bottom: 10, borderRadius: 10}}/>}
            <Icon name="ios-images" style={{ color: 'white', fontSize: 36 }} />
          </View>
          <MaterialCommunityIcons name="google-circles-communities" style={{ color: 'white', fontSize: 36 }} />
        </View>
      </Camera>
    </View> 
  );
};

关键修复点说明

  • 移除无效导入:删除Permissions(Expo已将权限请求整合到对应模块)和CameraType(expo-camera无此直接导出)的导入,避免产生undefined变量。
  • 修正拍照逻辑:将if (Camera)改为if (camera),判断实际的相机实例而非类本身。
  • 添加Camera核心属性:给Camera组件传入type属性,确保前后摄像头切换功能生效。
  • 优化预览图片样式:调整拍照后图片的尺寸和定位,避免覆盖拍照按钮。
  • 完善权限状态处理:添加权限请求中的加载状态,避免页面渲染空内容。
  • 修正图标名称:将不存在的campfire图标替换为NativeBase支持的fire图标(如需自定义图标,需确保图标库已正确配置)。

内容的提问来源于stack exchange,提问作者iamareactnativerookie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:35:23