Apollo GraphQL条件执行useQuery时作用域外变量访问TypeScript报错如何解决
问题原因
- 违反React Hook调用规则:Hook不允许写在条件分支、循环等代码块中,必须在组件顶层调用,否则会出现Hook调用顺序错乱的问题。
- 变量作用域问题:你在
if代码块内声明的loadingQuery是块级作用域变量,仅在块内可访问,return模板在块外,自然无法读取到该变量,因此触发TypeScript报错。
最优解决方案:使用useQuery的skip参数
Apollo Client的useQuery原生提供了skip配置项,专门用于条件触发查询,完全不需要手动把Hook写在条件分支里:
// 直接在组件顶层调用useQuery const { data, loading: loadingQuery } = useQuery(MyQuery, { skip: !executeMyQuery // 当executeMyQuery为false时,不会发起查询请求 }); return ( <View> { /* ... 部分代码省略 ... */ } { executeMyQuery && loadingQuery ? <Text>Query is loading...</Text> { /* ... 部分代码省略 ... */ } : null } </View> );
这种写法的优势:
- 完全符合React Hook调用规则,不会出现顺序问题
loadingQuery是组件作用域变量,TypeScript可以正常识别,不会报找不到变量的错误- 当
executeMyQuery为false时,loading默认返回false,配合你模板里的executeMyQuery前置判断,只会在查询实际触发时才校验加载状态,完全符合你的需求。
可选方案:抽离为独立子组件
如果你确实有特殊场景需要条件调用查询,可以把查询相关的逻辑抽成单独的子组件,父组件条件渲染子组件即可:
// 抽离单独的查询子组件 const QueryContent = () => { const { data, loading: loadingQuery } = useQuery(MyQuery); if (loadingQuery) { return <Text>Query is loading...</Text> } // 其他查询成功后的渲染逻辑 return <>{/* 渲染data内容 */}</> } // 父组件逻辑 return ( <View> {executeMyQuery && <QueryContent />} </View> )
内容的提问来源于stack exchange,提问作者Z0q
相关产品推荐
相关产品推荐

