React Native API数据获取报错:未处理Promise拒绝与JSON解析错误
解决Unhandled promise rejection + JSON Parse错误
Hey,这个错误我之前调试API的时候也碰到过,咱们一步步拆解问题,找到根源:
错误原因解析
你看到的 Unhandled promise rejection: SyntaxError: JSON Parse error: Unexpected identifier "object" 本质上是两个问题:
- 未捕获的Promise异常:你的
getNews调用没有错误处理,一旦请求失败或解析出错,Promise会被拒绝但没被捕获。 - JSON解析失败:这说明你尝试解析的内容不是有效的JSON字符串——大概率是
getNews已经返回了一个JavaScript对象,但你(或者getNews内部)又重复调用了JSON.parse(),或者API本身返回的不是合法JSON(比如错误页HTML、格式错乱的字符串)。
分步排查&修复
1. 先给异步请求加上错误捕获
首先解决未处理的Promise问题,给getDetail加上try/catch,同时打印返回结果,看看实际拿到的是什么:
const getDetail = async () => { try { const fetchedNews = await getNews(0); console.log('getNews返回的原始数据:', fetchedNews); // 关键:看这里的输出 setNews(fetchedNews) } catch (err) { console.error('获取数据时出错:', err); // 这里可以加用户可见的错误提示,比如显示"加载失败" } }
2. 检查getNews函数的实现
打开../API/fetchData里的getNews,看看是不是重复解析了JSON。比如错误写法是这样的:
// ❌ 错误示例:重复解析JSON export async function getNews(id) { const res = await fetch(`your-api-url/${id}`); const data = await res.json(); // 这里已经把响应解析成对象了 return JSON.parse(data); // 又解析一次,必然报错! }
正确的写法应该是直接返回解析后的结果,还要加上响应状态校验:
// ✅ 正确示例 export async function getNews(id) { const res = await fetch(`your-api-url/${id}`); // 先校验响应状态,避免把错误页当成JSON解析 if (!res.ok) { throw new Error(`请求失败,状态码:${res.status}`); } const data = await res.json(); return data; // 返回已经解析好的对象/数组 }
3. 修正useEffect的依赖数组
你现在写的useEffect(() => { getDetail() }, [0])虽然能工作,但不符合规范——如果想让请求只在组件挂载时执行一次,应该用空数组[]作为依赖:
useEffect(() => { getDetail(); }, []); // 空数组 = 仅挂载时执行一次
4. 验证API响应本身
如果上面的步骤都没问题,直接用Postman或者浏览器访问你的API接口,看看返回的是不是标准JSON格式。比如如果返回的是"[object Object]"这种字符串,那肯定解析失败,这时候需要后端修复响应格式,或者前端在解析前先处理这种异常情况。
修改后的完整代码示例
import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet } from 'react-native'; import {getNews} from '../API/fetchData'; export function NewsScreen() { const [news, setNews] = useState ([]); useEffect(() => { getDetail(); }, []); const getDetail = async () => { try { const fetchedNews = await getNews(0); console.log('返回数据:', fetchedNews); // 确保设置的是数组,避免非数组数据导致后续渲染出错 setNews(Array.isArray(fetchedNews) ? fetchedNews : []); } catch (err) { console.error('获取新闻失败:', err); } } return ( <View> <Text>新闻列表</Text> {/* 后续可以在这里添加FlatList渲染news数据 */} </View> ) }; export default NewsScreen;
内容的提问来源于stack exchange,提问作者user13390075
相关产品推荐
相关产品推荐

