二次访问JSON文件触发TypeError:无法将null/undefined转为对象
问题:访问JSON文件时触发
TypeError: Cannot convert undefined or null to object错误 尝试完成第二个挑战时触发上述错误,已知挑战"8738-37cc"已完成,但多次访问对应JSON文件均失败。
相关代码片段
1. 任务获取函数
/** * Retrieve the tasks for the current challenge from the API * Updates the Guide State with the retrieved tasks */ function fetchTasks() { //Build API Endpoint based on current challenge in Application State const fetchURL = appContext.data.challenges && appContext.data.currentChallenge !== undefined ? `${APIUrl}challenge/${appContext.data.challenges[appContext.data.currentChallenge]}` : ""; fetch(fetchURL) .then((response) => response.json()) .then((json) => { setGuideState({ ...guideState, loaded: true, data: json, tasks: Object.entries(json.tasks), }); }) .catch((ERROR) => console.error(`API challenge ERROR (${ERROR})`)); }
2. TypeScript接口定义
export interface AppStateType{ challenges?: string[]; globalLoadedState: boolean; overlay: "none"|"intro"|"outro"; nextChallenge: ()=>void; } export let AppContext = React.createContext<{data: AppStateType, setData: any}>({data:{globalLoadedState:false, overlay:"none", nextChallenge: () => {}}, setData: ()=>{}});
3. 目标JSON文件内容
{"8738-38dd": {"title":"Passwords", "definition":"Lorem ipsum passwords.....", "isCompleted":false, "TaskIDs":["8275-gm12","8275-hu99","8275-io91","8275-ja55","8275-kq31"]}, "8738-37cc": {"title":"Updates", "definition":"Lorem ipsum updates.....", "isCompleted":true, "TaskIDs":["8275-42ae","8275-ad69","8275-ba67","8275-cb44","8275-dn31","8275-en12","8275-fr56"]}}
问题分析与修复方案
核心问题
错误直接来自Object.entries(json.tasks):你的JSON返回结构里根本没有tasks字段,只有TaskIDs数组,调用Object.entries处理undefined就会触发该报错。另外,fetchURL的拼接逻辑存在索引越界或空数组的隐患,可能导致请求返回无效数据。
修复步骤
修正数据访问逻辑:
替换json.tasks为实际存在的json.TaskIDs,按需转换为需要的格式:.then((json) => { // 将TaskIDs转为[任务ID, 默认状态]的键值对结构,可根据需求调整 const tasks = json.TaskIDs ? json.TaskIDs.map(id => [id, false]) : []; setGuideState({ ...guideState, loaded: true, data: json, tasks: tasks, }); })增强请求合法性检查:
避免无效请求:function fetchTasks() { const { challenges, currentChallenge } = appContext.data; const challengeId = challenges?.[currentChallenge]; // 检查挑战ID是否有效 if (!challengeId) { console.error("无效的挑战ID"); return; } const fetchURL = `${APIUrl}challenge/${challengeId}`; fetch(fetchURL) .then((response) => { // 检查HTTP响应状态 if (!response.ok) throw new Error(`请求失败:${response.status}`); return response.json(); }) .then((json) => { const tasks = json.TaskIDs ? json.TaskIDs.map(id => [id, false]) : []; setGuideState({ ...guideState, loaded: true, data: json, tasks: tasks, }); }) .catch((ERROR) => console.error(`API challenge ERROR (${ERROR})`)); }完善类型定义(可选):
补充挑战数据的类型约束,避免后续类型错误:export interface ChallengeDataType { title: string; definition: string; isCompleted: boolean; TaskIDs: string[]; } export interface AppStateType{ challenges?: string[]; currentChallenge?: number; globalLoadedState: boolean; overlay: "none"|"intro"|"outro"; nextChallenge: ()=>void; }
内容的提问来源于stack exchange,提问作者Magnus Helverskov
相关产品推荐
相关产品推荐

