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

使用Expo Image Picker遇未处理Promise拒绝警告,求排查

解决Expo Image Picker的"Possible Unhandled Promise Rejection"警告

问题根源

你的代码里有两处会触发该警告的问题:

  • useEffect回调误用async函数:React要求useEffect的回调要么返回清理函数,要么返回undefined。async函数默认返回Promise,这会让React误判为无效的清理函数,进而引发警告。
  • 未捕获异步操作异常:requestMediaLibraryPermissionsAsync和launchImageLibraryAsync都是异步Promise操作,一旦出现错误(比如权限请求失败、图片选择流程中断),Promise会被拒绝,但你没有添加错误捕获逻辑,导致未处理的Promise拒绝警告。

修复后的代码

import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { Platform, StyleSheet, Text, View, Button, Image } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import Constants from 'expo-constants';

export default function App() {
  const [image, setImage] = useState(null);

  // 把async逻辑封装到内部函数,避免直接给useEffect传async回调
  useEffect(() => {
    const requestPermissions = async () => {
      if (Platform.OS !== 'web') {
        try {
          const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
          if (status !== 'granted') {
            alert('权限被拒绝!');
          }
        } catch (error) {
          console.error('请求权限出错:', error);
        }
      }
    };

    requestPermissions();
  }, []);

  const PickImage = async () => {
    try {
      let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.All, // 修正原代码拼写错误:mediaTypesOptions → MediaTypeOptions
        allowsEditing: true,
        aspect: [4, 3],
        quality: 1
      });
      console.log(result);
      // Expo SDK 48+ 取消字段从cancelled改为canceled,低版本保持cancelled即可
      if (!result.canceled) { 
        setImage(result.uri);
      }
    } catch (error) {
      console.error('选择图片出错:', error);
    }
  };

  return (
    <View style={styles.container}>
      <Button title="选择图片" onPress={PickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

关键修复点说明

  1. 重构useEffect逻辑:
    不再直接给useEffect传async回调,而是在内部定义async函数并调用,确保useEffect回调返回undefined,符合React的规则。
  2. 添加try/catch捕获异常:
    对所有await的异步操作包裹try/catch,确保Promise拒绝时能被捕获处理,彻底消除未处理Promise警告。
  3. 修正API拼写错误:
    原代码中ImagePicker.mediaTypesOptions.All是错误写法,正确枚举为ImagePicker.MediaTypeOptions.All。
  4. 字段兼容性调整:
    Expo SDK 48及以上版本中,图片选择结果的取消字段从cancelled改为canceled,可根据你的SDK版本自行调整。

内容的提问来源于stack exchange,提问作者이소민

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:54:22