你如何动态控制 react apollo-client 查询启动?

Posted

技术标签:

【中文标题】你如何动态控制 react apollo-client 查询启动?【英文标题】:How do you dynamically control react apollo-client query initiation? 【发布时间】:2017-03-10 20:34:48 【问题描述】:

使用apollo-client 查询包装的 React 组件将自动发起对服务器的数据调用。

我想仅针对特定用户输入触发数据请求。

You can pass the skip option in the query options - 但这意味着 refetch() 函数没有作为组件提供给组件;并且似乎在 prop 更新时不会动态评估 skip 的值。

我的用例是地图组件。我只希望在用户按下按钮时加载标记的数据,而不是在初始组件安装或位置更改时加载。

下面的代码示例:

// GraphQL wrapping
Explore = graphql(RoutesWithinQuery, 
  options: ( displayedMapRegion ) => (
    variables: 
      scope: 'WITHIN',
      targetRegion: mapRegionToGeoRegionInputType(displayedMapRegion)
    ,
    skip: ( targetResource, searchIsAllowedForMapArea ) => 
      const skip = Boolean(!searchIsAllowedForMapArea || targetResource != 'ROUTE');
      return skip;
    ,
  ),
  props: ( ownProps, data:  loading, viewer, refetch ) => (
    routes: viewer && viewer.routes ? viewer.routes : [],
    refetch,
    loading
  )
)(Explore);

【问题讨论】:

报告跳过仍然不适用于此用例。现在你可能不得不使用 Apollo 来手动获取自己。 【参考方案1】:

要包含基于受道具更改影响的条件的 HoC,您可以使用recompose 中的branch

branch(
  test: (props: Object) => boolean,
  left: HigherOrderComponent,
  right: ?HigherOrderComponent
): HigherOrderComponent

检查:https://github.com/acdlite/recompose/blob/master/docs/API.md#branch

对于这个特定的例子,看起来像:

const enhance = compose(
  branch(

    // evaluate condition

    ( targetResource, searchIsAllowedForMapArea ) =>
      Boolean(!searchIsAllowedForMapArea || targetResource != 'ROUTE'),

    // HoC if condition is true

    graphql(RoutesWithinQuery, 
      options: ( displayedMapRegion ) => (
        variables: 
          scope: 'WITHIN',
          targetRegion: mapRegionToGeoRegionInputType(displayedMapRegion)
        ,
      ),
      props: ( ownProps, data:  loading, viewer, refetch  ) => (
        routes: viewer && viewer.routes ? viewer.routes : [],
        refetch,
        loading
      )
    )
  )
);

Explore = enhance(Explore);

【讨论】:

这太复杂了。让我想退出apollo 生态系统【参考方案2】:

我有一个类似的用例,我只想在用户点击时加载数据。

我没有尝试过by pencilcheck above 给出的 withQuery 建议。但我在其他地方看到了同样的建议。我会尝试一下,但与此同时,这就是我让它工作的方式based off a discussion on github:

./loadQuery.js

注意:我使用的是跳过指令:

const LOAD = `
query Load($ids:[String], $skip: Boolean = false) 
  things(ids: $ids) @skip(if: $skip) 
     title
  
`

LoadMoreButtonWithQuery.js

这里我使用withState高阶函数添加一个标志和一个标志设置器来控制skip

import  graphql, compose  from 'react-apollo';
import  withState  from 'recompose';
import LoadMoreButton from './LoadMoreButton';
import LOAD from './loadQuery';

export default compose(
    withState('isSkipRequest', 'setSkipRequest', true),
    graphql(
      gql(LOAD),
      
        name: 'handleLoad',
        options: (ids, isSkipRequest) => (
          variables: 
            ids,
            skip: isSkipRequest
          ,
        )
      
    ),
)(Button);

./LoadMoreButton.js

这里我必须手动“翻转”使用withState 添加的标志:

export default props => (
    <Button onClick=
        () => 
            props.setSkipRequest(false); // setter added by withState
            props.handleLoad.refetch();
        
     >+</Button>
);

坦率地说,我对此有点不满意,因为它引入了一组新的布线(由“withState”组成)。它也没有经过实战测试 - 我只是让它工作,然后我来到 *** 来检查更好的解决方案。

【讨论】:

以上是关于你如何动态控制 react apollo-client 查询启动?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo-client (react) - 更新创建突变 - “在对象 (ROOT_QUERY) 上找不到字段 Fund()”

如何与另一个查询共享缓存的 apollo-client 数据

javascript React-Native Apollo-client初始化文件

设置 apollo-client 标头时出现 NetworkError

React 动态菜单

GraphQL _ Apollo-client - 直接在组件中传递 guery 变量