防止接口异常导致页面报错崩溃
0.前言
防止后端坑B,某次不按约定返回一个不正常的数据格式,导致事故。
1.直接解构接口数据
// 模拟处理接口拿到的data
const handleData = (data)=> {
const { userinfo } = data;
const { id, age } = userinfo;
}
handleData({})
// Uncaught TypeError: Cannot destructure property 'id' of 'user' as it is undefined.
如果只是简单的给默认值
const handleData = (data)=> {
const { userinfo = {} } = data;
const { id, name } = userinfo;
}
handleData({userinfo: null})
// Uncaught TypeError: Cannot destructure property 'id' of 'userinfo' as it is null.
当userinfo为null的时候还会出现报错,因为如果一个对象的属性值不是=== undefined,那么默认值就不会生效。
I think a better approach is
const handleData = (data = {}) => {
const { user } = data;
const { id = '', name = '' } = user || {};
}
2.直接使用接口数组数据
// 模拟处理接口拿到的data
const handleData = (data)=> {
const { goodsList } = data;
const temList = goodsList.map((item)=> item.goodsname)
}
handleData({userList: null})
handleData({userList: 123})
handleData({userList: [ null, undefined ]})
// Uncaught TypeError: goodsList.map is not a function
很显然,后端的同事又发癫了。
I think a better approach is
const handleData = (data = {}) => {
const { goodsList = [] } = data;
if (!Array.isArray(goodsList)) {
console.warn('goodsList is not an array:', goodsList);
return [];
}
const temList = goodsList
.filter(item => item && typeof item === 'object')
.map(item => item.goodsname)
.filter(Boolean);
console.log('Processed goods names:', temList);
return temList;
};
// 测试各种情况
console.log(handleData({userList: null}));
console.log(handleData({userList: 123}));
console.log(handleData({userList: [ null, undefined ]}));
console.log(handleData({goodsList: [{goodsname: 'Apple'}, null, {goodsname: 'Banana'}]}));
3.为什么有时候不报错
('').name
(123).name
感觉好像会报错,事实上并没有报错。因为除了null和undefined这俩个以外,其他的基本类型都会被打包成对象,以便能使用对象的方法,所以要重点防范null和undefined
4.页面一直loading
有时候写了一个loading,async/await 报错未捕获的情况下又不处理loading就会一直loading下去。
const List = () => {
const [loading, setLoading] = useState(false);
const getData = async () => {
setLoading(true);
try {
const res = await queryData();
setLoading(false);
} catch (error) {
console.log('===error===',error)
setLoading(false);
}
}
}