如何基于Apollo手动发送GraphQL请求(避开组件渲染触发)
这个问题很常见!你当前使用的graphql高阶组件默认会在组件挂载时自动执行查询,要实现手动触发(比如按钮点击),可以根据组件类型选择下面两种方案:
1. 函数组件:使用useLazyQuery钩子
这是Apollo Client推荐的函数组件方案,useLazyQuery不会在组件挂载时自动发起请求,而是返回一个可手动调用的触发函数,以及查询结果的状态(加载中、错误、数据)。
示例代码:
import { useLazyQuery, gql } from '@apollo/client'; // 定义你的查询 const HelloQuery = gql` query Hello { hello } `; function MyComponent() { // getHello是触发查询的函数,第二个参数包含查询的状态和结果 const [getHello, { loading, error, data }] = useLazyQuery(HelloQuery); return ( <div> {/* 点击按钮时触发查询 */} <button onClick={() => getHello()}>获取Hello数据</button> {/* 渲染查询状态 */} {loading && <p>加载中...</p>} {error && <p>查询出错:{error.message}</p>} {data && <p>查询结果:{data.hello}</p>} </div> ); } export default MyComponent;
如果需要传递变量给查询,只需要在调用触发函数时传入:
getHello({ variables: { yourVariable: 'value' } })
2. 类组件:直接调用ApolloClient实例
如果你的组件是类组件,可以通过withApollo高阶组件将ApolloClient实例注入到组件props中,然后在按钮点击事件里手动调用client.query()方法。
示例代码:
import { withApollo, gql } from '@apollo/client'; import React from 'react'; const HelloQuery = gql` query Hello { hello } `; class MyComponent extends React.Component { state = { loading: false, error: null, data: null }; handleFetchHello = async () => { this.setState({ loading: true, error: null }); try { // 手动调用client的query方法发送请求 const response = await this.props.client.query({ query: HelloQuery // 如需传参:variables: { key: value } }); this.setState({ data: response.data, loading: false }); } catch (err) { this.setState({ error: err.message, loading: false }); } }; render() { const { loading, error, data } = this.state; return ( <div> <button onClick={this.handleFetchHello}>获取Hello数据</button> {loading && <p>加载中...</p>} {error && <p>查询出错:{error}</p>} {data && <p>查询结果:{data.hello}</p>} </div> ); } } // 用withApollo包裹组件,将client注入到props export default withApollo(MyComponent);
简单总结:原来的graphql高阶组件是声明式的,自动管理查询时机;而上面两种方案是命令式的,完全由你控制请求发送的时机,非常适合需要用户交互触发的场景。
内容的提问来源于stack exchange,提问作者Mohamed Taboubi
相关产品推荐
相关产品推荐

