Expo-Camera调用takePictureAsync报错:undefined问题求助
问题原因与修复方案
问题根源
你在MeasurementCamera组件里犯了一个关键错误:把父组件传入的同一个ref同时绑定给了Camera组件和useImperativeHandle。
父组件的cameraRef最终指向的是useImperativeHandle返回的包含takePicture方法的对象,而不是Camera实例。所以当你在takePicture里调用ref.current.takePictureAsync时,这个ref.current是自定义的方法集合,自然没有takePictureAsync这个原生Camera方法,导致报错。
修复步骤
在MeasurementCamera内部创建一个独立的ref来管理Camera实例,父组件传入的ref只用来暴露自定义方法,两者彻底分离:
修改后的MeasurementCamera代码
import { useState, useEffect, useImperativeHandle, forwardRef, useRef } from 'react' import { StyleSheet } from "react-native" import { Camera } from 'expo-camera' import Text from './Text' const MeasurementCamera = forwardRef((props, ref) => { const [hasPermission, setHasPermission] = useState(null) // 内部单独创建ref管理Camera实例 const cameraRef = useRef(null) useEffect(() => { const getPermission = async () => { const { status } = await Camera.requestCameraPermissionsAsync() setHasPermission(status === 'granted') } getPermission() }, []) const takePicture = async () => { // 这里用内部的cameraRef访问Camera实例 if (cameraRef.current) { const options = { quality: 1, base64: true } const picture = await cameraRef.current.takePictureAsync(options) console.log(picture.uri) } } // 用父组件传入的ref暴露takePicture方法 useImperativeHandle(ref, () => ({ takePicture })) if (hasPermission === null) { return <Text>Requesting for camera permission</Text> } if (hasPermission === false) { return <Text>No access to camera</Text> } return ( <Camera ref={cameraRef} // 绑定内部的cameraRef style={StyleSheet.absoluteFillObject} /> ) }) MeasurementCamera.displayName = 'MeasurementCamera' export default MeasurementCamera
MeasurementCameraScreen无需修改
父组件的代码保持原样即可,点击按钮时依然通过cameraRef.current.takePicture()调用暴露的方法。
为什么这样能解决问题
- 内部的
cameraRef专门用来引用Camera原生组件,确保能访问到takePictureAsync方法 - 父组件传入的
ref通过useImperativeHandle只暴露我们需要的takePicture方法,和内部Camera实例的引用彻底解耦 - 拆分组件的结构得以保留,同时功能正常运行
内容的提问来源于stack exchange,提问作者katjasdf
相关产品推荐
相关产品推荐

