如何在使用Redux connect的React类组件中访问ApolloProvider的client?
类组件接入Apollo Client实现方案
核心结论
- 可以直接在类组件中访问全局ApolloClient实例,完全不需要在每个类组件中新建实例,全局仅需index.js中初始化的1个实例即可,确保缓存、请求状态全局统一,避免重复请求和数据不一致问题。
- 之前使用
withApollo丢失connect映射的props,是高阶组件包裹顺序错误导致的,调整顺序即可解决,也可以用更简单的context注入方式避免高阶组件嵌套问题。
实现方法
方法1:调整高阶组件包裹顺序
高阶组件的执行顺序为从右到左,你需要先让withApollo注入client属性,再用connect注入Redux的映射属性,两个高阶组件的属性会自动合并,不会丢失:
修改App.js的导出代码即可:
// 先引入withApollo import { withApollo } from '@apollo/client/react/hoc'; class App extends Component { componentDidMount() { // 直接通过props获取client实例使用 console.log(this.props.client) } render() { ... } } const mapStateToProps = (state) => { return { ... }; }; // 调整包裹顺序:先包withApollo,再包connect export default connect(mapStateToProps)(withApollo(App));
方法2:使用contextType直接注入(无需修改高阶组件结构)
如果不想修改现有高阶组件的嵌套逻辑,可以直接通过Apollo提供的Context直接获取实例,代码更简洁:
import { ApolloContext } from '@apollo/client'; class App extends Component { // 声明context类型,Apollo会自动把client实例注入到this.context static contextType = ApolloContext; componentDidMount() { // 直接通过context获取client实例 console.log(this.context) } render() { ... } } const mapStateToProps = (state) => { return { ... }; }; // 不需要修改原有导出逻辑 export default connect(mapStateToProps)(App);
方法3:在render方法中使用ApolloConsumer
如果只需要在渲染逻辑中使用client,不需要在生命周期调用,可以直接用ApolloConsumer组件包裹:
import { ApolloConsumer } from '@apollo/client'; class App extends Component { render() { return ( <ApolloConsumer> {client => ( // 渲染逻辑中直接使用client <div> {/* 你的组件内容 */} </div> )} </ApolloConsumer> ) } }
内容的提问来源于stack exchange,提问作者krisjanis-a
相关产品推荐
相关产品推荐

