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

React Native安卓应用出现Possible Unhandled Promise Rejection错误如何修复

问题根源

你遇到的Possible Unhandled Promise Rejection报错核心原因是异步请求没有添加错误捕获逻辑:调用getMovie、getTv时如果请求失败(比如传入的ID是剧集ID时调用电影查询接口会返回404错误),Promise抛出的异常没有被catch捕获,就会触发这个报错。

同时你的代码还存在几个逻辑问题:

  • 初始化movieDetail、movieTv的state为数组,但接口返回的是对象,后续访问movieDetail.title会出现逻辑隐患
  • 两个并行的请求接口会互相覆盖loaded状态,可能出现数据没加载完就提前标记为加载完成的问题
  • 组件return之后的console.log(movieTv.success)永远不会执行,属于无效代码
  • 没有判断路由参数是否存在的边界逻辑,极端情况会出现取空值报错

修复后的代码

Detail.js

import React, {useEffect, useState} from 'react';
import {Text, ActivityIndicator} from 'react-native';
import {getMovie, getTv} from '../services/services';

const Detail = ({route, navigation}) => {
    // 路由参数边界判断
    if (!route.params?.movieDetail?.id) {
        return <Text>参数错误</Text>
    }
    const movieId = route.params.movieDetail.id;

    // 初始化state改为空对象,匹配接口返回类型
    const [movieDetail, setMovieDetail] = useState({});
    const [movieTv, setMovieTv] = useState({});
    
    const [loaded, setLoaded] = useState(false);
    // 新增错误状态用于展示请求异常情况
    const [error, setError] = useState(null);

    useEffect(() => {
        // 统一处理两个并行请求
        const fetchData = async () => {
            const [movieRes, tvRes] = await Promise.allSettled([
                getMovie(movieId),
                getTv(movieId)
            ])
            // 处理电影请求结果
            if (movieRes.status === 'fulfilled' && movieRes.value) {
                setMovieDetail(movieRes.value)
            }
            // 处理剧集请求结果
            if (tvRes.status === 'fulfilled' && tvRes.value) {
                setMovieTv(tvRes.value)
            }
            setLoaded(true)
        }
        // 全局捕获请求异常
        fetchData().catch(err => {
            setError(err.message)
            setLoaded(true)
        })
    }, [movieId]);

    // 加载中状态
    if (!loaded) {
        return <ActivityIndicator size="large" style={{flex: 1, justifyContent: 'center'}} />
    }
    // 请求错误状态
    if (error) {
        return <Text>加载失败:{error}</Text>
    }

    return (
        <React.Fragment>
            {movieDetail.title ? <Text>{movieDetail.title}</Text> : <Text>{movieTv.name || '暂无数据'}</Text>}
        </React.Fragment>
    );
}

export default Detail;

可选优化(services.js增加统一错误捕获)

如果你想统一处理所有接口的报错,也可以直接在请求封装层添加异常捕获逻辑:

import axios from 'axios';

const apiUrl = 'https://api.themoviedb.org/3';
const apiKey = 'api_key=31a7f8174b1e2c29744ec644af796973';

// 获取热门电影
export const getPopularMovies = async () => {
    try {
        const resp = await axios.get(`${apiUrl}/movie/popular?${apiKey}`);
        return resp.data.results;
    } catch (err) {
        console.error('获取热门电影失败', err)
        return []
    }
};

// 获取即将上映电影
export const getUpcomingMovies = async () => {
    try {
        const resp = await axios.get(`${apiUrl}/movie/upcoming?${apiKey}`);
        return resp.data.results;
    } catch (err) {
        console.error('获取即将上映电影失败', err)
        return []
    }
};

// 获取热门剧集
export const getPopularTv = async () => {
    try {
        const resp = await axios.get(`${apiUrl}/tv/popular?${apiKey}`);
        return resp.data.results;
    } catch (err) {
        console.error('获取热门剧集失败', err)
        return []
    }
};

export const getFamilyMovies = async () => {
    try {
        const resp = await axios.get(`${apiUrl}/discover/movie?${apiKey}&with_genres=10751`);
        return resp.data.results;
    } catch (err) {
        console.error('获取家庭类电影失败', err)
        return []
    }
};

export const getMovie = async id => {
    try {
        const resp = await axios.get(`${apiUrl}/movie/${id}?${apiKey}`);
        return resp.data;
    } catch (err) {
        console.error('获取电影详情失败', err)
        return null
    }
};

export const getTv = async id => {
    try {
        const resp = await axios.get(`${apiUrl}/tv/${id}?${apiKey}`);
        return resp.data;
    } catch (err) {
        console.error('获取剧集详情失败', err)
        return null
    }
};

修复说明

  • 所有异步请求都添加了异常捕获逻辑,从根源解决未处理的Promise rejection报错
  • 用Promise.allSettled并行处理两个详情请求,不管其中一个是否成功都能正常返回结果,同时统一管理加载状态,避免状态被覆盖的问题
  • 补充了加载中、请求失败的边界状态展示,避免白屏
  • 修正了state初始化类型不匹配的问题
  • 补充了路由参数非空判断,避免极端情况出现空值报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:27:04