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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:48:24