React在useCallback中调用自定义Hook违反Hooks规则报错如何修复
问题原因
报错的核心原因是React Hooks的调用规则限制:所有Hook必须在React函数组件或者自定义Hook的顶层作用域调用,不能嵌套在回调函数、条件判断、循环等代码块中,你在useCallback的回调里调用useQueryBlablablaAction这个自定义Hook,自然触发了规则校验报错。
解决方案
这里提供两种适配不同场景的修改方案:
方案1:基于现有useQuery逻辑改造(适合需要缓存查询结果的场景)
步骤1:调整自定义Hook支持透传查询配置
给useGraphQLQuery增加配置参数,用来控制是否自动发起请求:
function useGraphQLQuery( name, query, variables = {}, queryOptions = {} ){ return useQuery(`bla${name}`, async () => { return request(endpoint, query, variables); }, queryOptions); }
同步修改useQueryBlablablaAction支持透传配置:
export function useQueryBlablablaAction(id, queryOptions = {}) { return useGraphQLQuery( 'blablablaAction', gql` mutation Mutation($ID: String!) { blablabla(Input: { ID: $ID }) { Status } } `, { ID: id }, queryOptions ); }
步骤2:组件顶层调用Hook,手动触发请求
在组件的顶层作用域调用自定义Hook,通过enabled: false禁止组件渲染时自动发起请求,再通过返回的refetch方法在点击时手动触发:
// 组件顶层调用Hook,关闭自动请求,拿到手动触发方法 const { refetch: sendBlablablaRequest } = useQueryBlablablaAction(id, { enabled: false }); // 点击回调里直接调用触发方法 const sendRequest = useCallback(() => { sendBlablablaRequest(); }, [sendBlablablaRequest]); // 按钮绑定逻辑保持不变 <Button variant="contained" onClick={sendRequest}> Disable </Button>
方案2:改用useMutation实现(更适配当前修改类操作的场景)
你当前的操作是GraphQL Mutation(数据修改操作),本身更适合用React Query提供的useMutation实现,不需要额外处理自动请求的逻辑,也更符合语义:
步骤1:封装Mutation专用的自定义Hook
// 新增GraphQL Mutation通用Hook function useGraphQLMutation(name, mutation) { return useMutation(async (variables) => { return request(endpoint, mutation, variables); }, { mutationKey: `bla${name}` }); } // 调整业务Hook用Mutation实现 export function useBlablablaAction() { return useGraphQLMutation( 'blablablaAction', gql` mutation Mutation($ID: String!) { blablabla(Input: { ID: $ID }) { Status } } ` ); }
步骤2:组件内调用
// 组件顶层调用Hook const { mutate: sendBlablablaRequest } = useBlablablaAction(); // 点击回调触发时传入参数 const sendRequest = useCallback(() => { sendBlablablaRequest({ ID: id }); }, [sendBlablablaRequest, id]); // 按钮绑定逻辑保持不变 <Button variant="contained" onClick={sendRequest}> Disable </Button>
内容的提问来源于stack exchange,提问作者GuillaumeC
相关产品推荐
相关产品推荐

