Redux与Apollo 2.x.x搭配使用问题及报错咨询
解决Redux与Apollo 2.x搭配问题及报错分析
首先,针对你遇到的Cannot read property 'reducer' of undefined报错,大概率是Apollo缓存实例未正确与Redux store关联导致的——要么你没把Apollo的reducer合并到Redux的根reducer里,要么缓存初始化时没有传入正确的store引用。
下面分两种场景说明如何搭配Redux和Apollo 2.x:
场景1:将Apollo缓存集成到Redux Store(共享状态)
如果你希望Apollo的GraphQL缓存和Redux应用状态共存于同一个store,需要用到apollo-cache-redux包:
步骤1:安装依赖
npm install apollo-client apollo-cache-redux apollo-link-http react-apollo redux react-redux
步骤2:配置Redux Store
在configureStore.js中,必须将Apollo提供的apolloReducer合并到你的根reducer中:
import { createStore, combineReducers } from 'redux'; import { apolloReducer } from 'apollo-cache-redux'; // 导入你的自定义reducers import userReducer from './reducers/userReducer'; // 合并Apollo reducer和自定义reducers const rootReducer = combineReducers({ apollo: apolloReducer, // 必须添加这个切片,Apollo会用它存储缓存 user: userReducer, // 你的应用状态 }); const store = createStore(rootReducer); export default store;
步骤3:创建Apollo Client并关联Redux缓存
单独创建Apollo配置文件(比如apollo/client.js):
import { ApolloClient } from 'apollo-client'; import { createHttpLink } from 'apollo-link-http'; import { ReduxCache } from 'apollo-cache-redux'; import store from '../store/configureStore'; // 创建GraphQL API链接 const httpLink = createHttpLink({ uri: 'https://your-graphql-api.com/graphql', // 替换为你的API地址 }); // 初始化Redux缓存,传入Redux store实例 const cache = new ReduxCache({ store }); // 创建Apollo客户端 const client = new ApolloClient({ link: httpLink, cache: cache, }); export default client;
步骤4:用双Provider包裹应用
在入口文件中,Redux的Provider要在外层,Apollo的Provider在内层:
import React from 'react'; import ReactDOM from 'react-dom'; import { Provider as ReduxProvider } from 'react-redux'; import { ApolloProvider } from 'react-apollo'; import AppRouter from './routers/AppRouter'; import registerServiceWorker from './registerServiceWorker'; import store from './store/configureStore'; import client from './apollo/client'; ReactDOM.render( <ReduxProvider store={store}> <ApolloProvider client={client}> <AppRouter /> </ApolloProvider> </ReduxProvider>, document.getElementById('root') ); registerServiceWorker();
场景2:Redux与Apollo独立管理状态(更简单)
如果不需要共享缓存,只是想同时用Redux管理应用状态、Apollo管理GraphQL数据,这种方式更简单,也不会出现你的报错:
步骤1:安装依赖
npm install apollo-client apollo-cache-inmemory apollo-link-http react-apollo redux react-redux
步骤2:正常配置Redux Store
configureStore.js里只需要处理你的自定义reducers:
import { createStore, combineReducers } from 'redux'; import userReducer from './reducers/userReducer'; const rootReducer = combineReducers({ user: userReducer, }); const store = createStore(rootReducer); export default store;
步骤3:独立创建Apollo Client
用默认的InMemoryCache,不需要关联Redux:
import { ApolloClient } from 'apollo-client'; import { createHttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const httpLink = createHttpLink({ uri: 'https://your-graphql-api.com/graphql', }); const cache = new InMemoryCache(); const client = new ApolloClient({ link: httpLink, cache: cache, }); export default client;
步骤4:双Provider包裹应用
和场景1一样,用两个Provider包裹应用即可,顺序不影响(但习惯上Redux在外层)。
你的报错修复建议
回到你遇到的错误,检查这几点:
- 是否忘记在
configureStore.js中导入并合并apolloReducer? - 创建
ReduxCache时有没有传入正确的store实例? - 是否误将
InMemoryCache和Redux reducer混用?
如果按场景2的方式配置,完全避开Redux和Apollo缓存的关联,应该能直接解决这个报错。
内容的提问来源于stack exchange,提问作者ramin karimian
相关产品推荐
相关产品推荐

