React Native 0.76使用react-native-camera报空对象引用错误求助
问题分析与解决:React Native 0.76 + react-native-camera 空指针错误
在React Native 0.76版本中使用react-native-camera组件时触发空指针错误,错误信息如下:
Attempt to invoke virtual method 'com.facebook.react.uimanager.events.EventDispatcher com.facebook.react.uimanager.UiManagerModule.getEventDispatcher()' on a null object reference
原实现代码
import React, { useRef, useState, useEffect } from 'react'; import { StyleSheet, View, Text } from 'react-native'; import { RNCamera } from 'react-native-camera'; const Registration = () => { const cameraRef = useRef(null); const [cameraReady, setCameraReady] = useState(false); useEffect(() => { // Handle camera initialization and permissions here if (cameraRef.current) { setCameraReady(true); } }, [cameraRef]); const handleCameraReady = () => { setCameraReady(true); }; return ( <View style={styles.container}> {cameraReady ? ( <RNCamera ref={cameraRef} style={styles.preview} type={RNCamera.Constants.Type.back} flashMode={RNCamera.Constants.FlashMode.on} androidCameraPermissionOptions={{ title: 'Permission to use camera', message: 'We need your permission to use your camera', buttonPositive: 'Ok', buttonNegative: 'Cancel', }} onCameraReady={handleCameraReady} /> ) : ( <Text>Camera is initializing...</Text> )} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'column', backgroundColor: 'black', }, preview: { flex: 1, justifyContent: 'center', alignItems: 'center', }, }); export default Registration;
错误原因分析
- 渲染逻辑倒置:用
cameraReady状态控制RNCamera的渲染,初始状态为false导致相机组件迟迟不挂载。后续即使权限通过,也无法触发相机渲染,形成死循环;当相机最终被渲染时,Native层事件回调可能因组件挂载时机异常,找不到有效的UiManagerModule实例,触发空指针。 - 无效的useEffect监听:
cameraRef是useRef对象,其引用不会变化,监听它的useEffect只会执行一次,且此时相机组件未渲染,cameraRef.current始终为null,逻辑完全无效。
解决方案
1. 调整渲染逻辑
移除cameraReady对RNCamera渲染的控制,直接渲染相机组件,用onCameraReady回调更新状态显示初始化完成提示,确保相机能正常挂载,避免Native层事件异常。
2. 完善权限检查
单独处理相机权限请求,避免权限未获取时组件出现异常。
3. 删除无效useEffect
移除监听cameraRef的useEffect,改用onCameraReady处理相机就绪后的状态更新。
修改后的代码
import React, { useRef, useState, useEffect } from 'react'; import { StyleSheet, View, Text, PermissionsAndroid } from 'react-native'; import { RNCamera } from 'react-native-camera'; const Registration = () => { const cameraRef = useRef(null); const [cameraReady, setCameraReady] = useState(false); const [hasPermission, setHasPermission] = useState(null); useEffect(() => { const requestCameraPermission = async () => { try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.CAMERA, { title: 'Permission to use camera', message: 'We need your permission to use your camera', buttonPositive: 'Ok', buttonNegative: 'Cancel', } ); setHasPermission(granted === PermissionsAndroid.RESULTS.GRANTED); } catch (err) { console.warn(err); setHasPermission(false); } }; requestCameraPermission(); }, []); const handleCameraReady = () => { setCameraReady(true); }; // 权限状态处理 if (hasPermission === null) { return <View style={styles.container}><Text>Requesting camera permission...</Text></View>; } if (hasPermission === false) { return <View style={styles.container}><Text>No access to camera</Text></View>; } return ( <View style={styles.container}> {/* 初始化提示叠加在相机预览上 */} {!cameraReady ? ( <Text style={styles.loadingText}>Camera is initializing...</Text> ) : null} <RNCamera ref={cameraRef} style={styles.preview} type={RNCamera.Constants.Type.back} flashMode={RNCamera.Constants.FlashMode.on} onCameraReady={handleCameraReady} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'black', justifyContent: 'center', alignItems: 'center', }, preview: { flex: 1, position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, }, loadingText: { color: 'white', fontSize: 18, zIndex: 1, }, }); export default Registration;
额外注意事项
- 确认react-native-camera版本兼容RN 0.76:旧版本组件可能不适配RN新架构变化,建议使用官方维护的最新版本。
- 清理项目缓存:修改代码后执行
npx react-native clean,再重新构建项目,避免旧Native缓存导致的异常。
内容的提问来源于stack exchange,提问作者dev vaibhav
相关产品推荐
相关产品推荐

