如何在React应用中结合使用Redux与基于Apollo Client的GraphQL
在Redux Action中通过Apollo Client获取GraphQL数据的实现方法
第一步:导出index.js中配置好的Apollo Client实例
你当前的Apollo Client实例仅在index.js的渲染逻辑中使用,没有对外导出,所以action文件无法访问到该实例。修改index.js代码,添加导出逻辑:
import React from "react"; import ReactDOM from "react-dom"; import App from './App.jsx'; import {BrowserRouter} from "react-router-dom"; import store from "./store"; import { Provider } from "react-redux"; import ApolloClient from 'apollo-boost'; import { ApolloProvider } from 'react-apollo'; import {InMemoryCache} from "@apollo/client"; // 添加export导出client实例 export const client = new ApolloClient({ uri: 'http://localhost:4000/graphql', cache: new InMemoryCache() }); ReactDOM.render( <React.StrictMode> <ApolloProvider client={client}> <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider> </ApolloProvider> </React.StrictMode>, document.getElementById("root") );
第二步:修改Redux Action文件,调用Client的查询方法
Apollo Client实例自带query方法,可在非组件环境下直接发起GraphQL查询,修改你的action代码如下:
import { FETCH_PRODUCTS, FETCH_PRODUCTS_FAIL, FETCH_PRODUCTS_SUCCESS } from "../types"; import {gql} from "apollo-boost"; // 导入刚才导出的client实例,注意根据你的实际文件路径调整导入路径 import { client } from '../index'; const getProductsQuery = gql` { category{ products{ name inStock gallery category prices{ currency amount } } } } ` const fetchProducts = () => async(dispatch) =>{ dispatch({ type: FETCH_PRODUCTS, }); try{ // 调用client.query方法发起查询 const { data } = await client.query({ query: getProductsQuery }); dispatch({ type:FETCH_PRODUCTS_SUCCESS, payload:data, }); } catch(error){ dispatch({ type: FETCH_PRODUCTS_FAIL, payload:error.message }); } } export {fetchProducts};
可选优化:通过Redux Thunk注入Client(避免路径导入问题)
如果你的项目层级复杂,导入index文件容易出现路径错误,可以在初始化redux store的时候,通过redux-thunk的withExtraArgument配置把client实例注入到thunk的参数中:
- 配置store的时候修改如下:
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import { client } from './index'; import rootReducer from './reducers'; // 把client作为额外参数注入thunk const store = createStore( rootReducer, applyMiddleware(thunk.withExtraArgument(client)) );
- 对应的action中直接从参数获取client即可,不需要导入:
const fetchProducts = () => async(dispatch, getState, client) =>{ // 后续逻辑和之前完全一致 }
完成以上配置后,获取到的GraphQL数据会通过dispatch存入redux store,你可以在任意组件中通过react-redux的useSelector访问到对应数据。
内容的提问来源于stack exchange,提问作者Sara Ghali
相关产品推荐
相关产品推荐

