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

React+Recompose动态GraphQL查询问题:data始终为undefined且无法等待加载

解决Recompose结合动态GraphQL查询时data为undefined的问题

嘿,我一眼就看出问题出在哪了——你把withProps和graphql高阶组件的用法搞混啦!withProps的作用是给组件添加额外的props,它根本不能直接返回graphql HOC,所以你的查询完全没被正确执行,自然data一直是undefined。

咱们一步步来修正这个问题:

1. 动态生成GraphQL查询的正确姿势

graphql HOC的第一个参数支持传入函数,这个函数会接收当前组件的props,然后返回对应的GraphQL查询。这样你就能直接根据match.params动态生成查询,完全不用绕withProps的弯路。

2. 用branch优雅处理加载/错误状态

你提到的showSpinnerWhileApolloLoading和showApolloError,可以用Recompose的branch来实现更清晰的逻辑(如果这两个是你已经封装好的HOC,直接正确组合就行)。

修正后的完整代码示例

import { compose, branch, renderComponent } from 'recompose';
import { graphql, gql } from 'react-apollo';
// 假设你有自定义的加载和错误组件
import LoadingSpinner from './LoadingSpinner';
import ApolloErrorView from './ApolloErrorView';

export const SimplePage = ({ match, route, data: { post } }) => (
  // 你的组件渲染逻辑
  <div>
    {post ? <h2>{post.title}</h2> : null}
  </div>
);

// 定义动态查询生成函数
const generateDynamicQuery = (params) => {
  // 根据传入的params返回对应的GraphQL查询
  return gql`
    query GetTargetPost($postId: ID!) {
      post(id: $postId) {
        id
        title
        content
      }
    }
  `;
};

// 封装加载状态分支:判断data.loading,是则显示Spinner
const withLoadingState = branch(
  ({ data }) => data.loading,
  renderComponent(LoadingSpinner)
);

// 封装错误状态分支:判断data.error,是则显示错误组件
const withErrorState = branch(
  ({ data }) => data.error,
  renderComponent(ApolloErrorView)
);

// 组合所有HOC,注意执行顺序:graphql要先执行,后续HOC才能拿到data
const enhance = compose(
  graphql(
    // 动态生成查询
    (props) => generateDynamicQuery(props.match.params),
    {
      // 传递动态变量
      options: (props) => ({
        variables: { postId: props.match.params.postId }
      })
    }
  ),
  withErrorState,
  withLoadingState
  // 如果用你自己封装的showApolloError/showSpinnerWhileApolloLoading,替换上面两个即可
  // showApolloError(),
  // showSpinnerWhileApolloLoading()
);

export default enhance(SimplePage);

关键细节解释

  • 动态查询的正确写法:graphql支持以函数作为第一个参数,能实时根据props生成查询,这是官方推荐的动态查询方式,比嵌套withProps可靠得多。
  • branch的作用:branch会根据第一个函数的返回值(true/false),决定渲染第二个参数的组件,还是继续把props传给原组件,完美适配加载/错误状态的切换逻辑。
  • HOC的执行顺序:compose是从右往左执行的,所以一定要把graphql放在最右侧(最先执行),这样后续处理状态的HOC才能拿到data props。

这样调整后,你的组件就能正确等待数据加载,data也不会再是undefined啦!

内容的提问来源于stack exchange,提问作者Elisa M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:51:03