React Navigation传参后调用fetch报错fetch is not a function
问题原因
这是典型的JavaScript局部变量覆盖全局API导致的错误:
你在Quiz组件顶层通过const { fetch } = route.params;解构出了名为fetch的路由参数,值为字符串"history"。根据JS作用域规则,这个局部变量的优先级高于全局提供的网络请求方法fetch,当你在getQuiz函数中执行fetch(url)时,实际是尝试把字符串"history"作为函数调用,因此抛出fetch is not a function的类型错误。添加timeout逻辑完全不涉及变量冲突的根因,自然无法解决问题。
修复方法
两种方案任选其一即可,优先推荐第一种:
- 方案1:重命名解构的路由参数,从根源避免命名冲突
修改Quiz页面的参数解构逻辑,把路由传入的参数重命名为和全局API不冲突的名称,同步修改URL拼接处的变量引用:const Quiz = ({ navigation, route }) => { // 解构时重命名参数,避免和全局fetch方法重名 const { fetch: quizCategory } = route.params; const getQuiz = async () => { setIsLoading(true); const url = `https://herokuapp.com/q/${quizCategory}`; const res = await fetch(url); const data = await res.json(); setQuestions(data.results); setOptions(generateOptionsAndShuffle(data.results[0])); setIsLoading(false); }; - 方案2:显式调用全局作用域下的fetch方法
如果不想修改参数名,可以在调用请求方法时明确指定全局对象下的fetch(React Native环境全局对象为global):const res = await global.fetch(url);
优化建议
给异步请求逻辑添加try/catch异常捕获,避免网络错误、接口返回格式异常等场景下再次出现未捕获的Promise异常,参考写法:
const getQuiz = async () => { setIsLoading(true); try { const { fetch: quizCategory } = route.params; const url = `https://herokuapp.com/q/${quizCategory}`; const res = await fetch(url); const data = await res.json(); setQuestions(data.results); setOptions(generateOptionsAndShuffle(data.results[0])); } catch (err) { console.error('获取题目失败', err); // 可在此处添加错误提示UI逻辑 } finally { setIsLoading(false); } };
内容的提问来源于stack exchange,提问作者Bhavya Sharma
相关产品推荐
相关产品推荐

