You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在React-Apollo中通过Redux获取变量调用GraphQL查询的问题

组件结合Redux与Apollo GraphQL的问题排查与解决

我的问题情况

我现在碰到一个棘手的问题:我的React组件需要调用GraphQL查询,但查询依赖的变量只能从Redux Store里获取。我已经尝试用react-apollo的compose把Redux的connect和graphql高阶组件结合起来用,但不仅没法从reducer拿到数据,连查询都加载不起来。而且看起来我的Store是空的,想确认是不是Redux的使用方式出了问题。

我的代码示例如下:

class abc extends Component { 
  componentWillMount() { 
    console.log(this.props.variableData); // 这里拿到的是空对象
  } 
} 

function mapDispatchToProps(dispatch) { 
  return bindActionCreators({ variableDataFetchAction }, dispatch); 
} 

function mapStateToProps(state) { 
  return { 
    variableData: state.reducerName.variableData, 
  } 
} 

export default compose( 
  connect(mapStateToProps, mapDispatchToProps), 
  graphql(MyQuery, { 
    options: props => { 
      return { ....., 
        variables: props.variableData, 
      }; 
    }, 
  }), 
)(abc); 

可能的问题原因与解决办法

我帮你梳理几个最可能的问题点,你可以逐一排查:

1. compose的执行顺序搞反了

这是最常见的坑!compose的执行逻辑是从右到左的,你现在把connect放在最左边,graphql放在右边,这意味着graphql高阶组件会先对组件进行包装,这时候组件还没和Redux建立连接,自然拿不到props.variableData。

修正方法:调换两者的顺序,让connect先执行(也就是放在compose的最右侧),把Redux的数据注入props后,再传给graphql的配置:

export default compose(
  graphql(MyQuery, {
    options: props => {
      // 现在这里就能拿到Redux注入的props了
      return {
        variables: props.variableData,
      };
    },
  }),
  connect(mapStateToProps, mapDispatchToProps),
)(abc);

2. 异步数据加载的时机问题

如果variableData是通过异步action(比如你的variableDataFetchAction)获取的,那在componentWillMount这个生命周期里,数据大概率还没请求回来,所以打印出来是空对象很正常。而且componentWillMount已经被React官方废弃了,建议换成componentDidMount。

修正方法:

  • 在componentDidMount里触发异步action获取数据
  • 在graphql的options里加判断,只有当variableData有有效数据时才执行查询,否则跳过:
graphql(MyQuery, {
  options: props => {
    // 检查variableData是否有有效内容,没有的话跳过查询
    const hasValidData = Object.keys(props.variableData).length > 0;
    return {
      skip: !hasValidData,
      variables: props.variableData,
    };
  },
}),

3. Redux Store的配置问题

如果Store本身是空的,那就要检查这几点:

  • 确认创建Store时,用combineReducers把你的reducerName正确合并进去了,比如:
import { combineReducers, createStore } from 'redux';
import reducerName from './yourReducer';

const rootReducer = combineReducers({
  reducerName, // 这里要确保key和你mapStateToProps里的一致
});

const store = createStore(rootReducer);
  • 检查variableDataFetchAction是否正确触发,对应的reducer有没有处理这个action的类型,把数据正确存入state.reducerName.variableData里。
  • 可以用Redux DevTools查看Store的状态变化,直观看到variableData有没有被正确存入。

4. Provider的包裹问题

确保你的组件被正确包裹在Redux的Provider和Apollo的ApolloProvider里面,比如:

import { Provider } from 'react-redux';
import { ApolloProvider } from '@apollo/client';
import store from './store';
import client from './apolloClient';

ReactDOM.render(
  <Provider store={store}>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </Provider>,
  document.getElementById('root')
);

修正后的完整代码示例

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { graphql, compose } from '@apollo/client/react/hoc';
import MyQuery from './MyQuery';
import { variableDataFetchAction } from './actions';

class abc extends Component {
  componentDidMount() {
    // 触发异步action获取数据
    this.props.variableDataFetchAction();
  }

  componentDidUpdate(prevProps) {
    // 监听variableData的变化,调试用
    if (prevProps.variableData !== this.props.variableData) {
      console.log('最新的variableData:', this.props.variableData);
    }
  }

  render() {
    // 根据查询状态渲染内容
    if (this.props.data.loading) return <div>加载中...</div>;
    if (this.props.data.error) return <div>出错了:{this.props.data.error.message}</div>;
    
    return <div>查询结果:{JSON.stringify(this.props.data)}</div>;
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ variableDataFetchAction }, dispatch);
}

function mapStateToProps(state) {
  // 给个默认空对象,避免undefined
  return {
    variableData: state.reducerName.variableData || {},
  };
}

export default compose(
  graphql(MyQuery, {
    options: props => {
      const hasValidData = Object.keys(props.variableData).length > 0;
      return {
        skip: !hasValidData,
        variables: props.variableData,
      };
    },
  }),
  connect(mapStateToProps, mapDispatchToProps),
)(abc);

内容的提问来源于stack exchange,提问作者Naveen Vignesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:57:53