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才能拿到dataprops。
这样调整后,你的组件就能正确等待数据加载,data也不会再是undefined啦!
内容的提问来源于stack exchange,提问作者Elisa M.
相关产品推荐
相关产品推荐

