如何使用 react-apollo graphql 确定突变加载状态

Posted

技术标签:

【中文标题】如何使用 react-apollo graphql 确定突变加载状态【英文标题】:How to determine mutation loading state with react-apollo graphql 【发布时间】:2017-01-15 17:41:57 【问题描述】:

2018 年更新:Apollo Client 2.1 添加了一个新的 Mutation 组件,该组件添加了 loading 属性。请参阅下面的@robin-wieruch 的答案以及此处的公告https://dev-blog.apollodata.com/introducing-react-apollo-2-1-c837cc23d926 继续阅读原始问题,该问题现在仅适用于早期版本的 Apollo。


使用react-apollo (v0.5.2) 中的graphql 高阶组件的当前版本,我没有看到有记录的方式来通知我的UI 一个突变正在等待服务器响应。我可以看到earlier versions of the package 会发送一个指示加载的属性。

查询仍会收到此处记录的加载属性:http://dev.apollodata.com/react/queries.html#default-result-props

我的应用程序也在使用 redux,所以我认为一种方法是将我的组件连接到 redux 并传递一个函数属性,该属性将使我的 UI 进入加载状态。然后在将我的 graphql 突变重写为属性时,我可以调用更新 redux 存储。

大概是这样的:

function Form( handleSubmit, loading, handleChange, value ) 
  return (
    <form onSubmit=handleSubmit>
      <input
        name="something"
        value=value
        onChange=handleChange
        disabled=loading
      />
      <button type="submit" disabled=loading>
        loading ? 'Loading...' : 'Submit'
      </button>
    </form>
  );


const withSubmit = graphql(
  gql`
    mutation submit($something : String) 
      submit(something : $something) 
        id
        something
      
    
  `, 
  
    props: ( ownProps, mutate ) => (
      async handleSubmit() 
        ownProps.setLoading(true);
        try 
          const result = await mutate();
         catch (err) 
          // @todo handle error here
        
        ownProps.setLoading(false);
      ,
    ),
  
);

const withLoading = connect(
  (state) => ( loading: state.loading ),
  (dispatch) => (
    setLoading(loading) 
      dispatch(loadingAction(loading));
    ,
  )
);

export default withLoading(withSubmit(Form));

我很好奇是否有更惯用的方法来通知 UI 突变是“正在进行中”。谢谢。

【问题讨论】:

问自己完全相同的问题(redux + apollo 客户端:突变加载状态)。如今(几周后)我没有找到更多关于它的线索。我仍然使用与您相同的方法... 突变是从组件本身内部调用的。在运行突变之前将自定义加载状态设置为 true 以及在突变返回后再次将其设置为 false 有什么反对意见? 谢谢,@marktani。是的,这样做是可以的。使用 react-apollo,查询会在请求进行中时自动设置加载属性,因此我想确保我没有错过对突变执行相同操作的内置方法。 【参考方案1】:

任何偶然发现这个问题的人,因为Apollo Client 2.1 您可以访问查询和突变component's render props function 中的这些属性。

import React from "react";
import  Mutation  from "react-apollo";
import gql from "graphql-tag";

const TOGGLE_TODO = gql`
  mutation ToggleTodo($id: Int!) 
    toggleTodo(id: $id) 
      id
      completed
    
  
`;

const Todo = ( id, text ) => (
  <Mutation mutation=TOGGLE_TODO variables= id >
    (toggleTodo,  loading, error, data ) => (
      <div>
        <p onClick=toggleTodo>
          text
        </p>
        loading && <p>Loading...</p>
        error && <p>Error :( Please try again</p>
      </div>
    )
  </Mutation>
);

注意:示例代码取自 Apollo Client 2.1 发布博客文章。

【讨论】:

能否知道加载进度(%)? 由于是HTTP请求,所以不知道进度。您发送请求并等待响应返回。 HTTP 请求可以提供进度状态。我以前在 axios 库中使用过它。这是 API,注意“onprogress”事件:developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/upload【参考方案2】:

我已经重新发布了this question on github,建议的解决方案是使用类似于反应高阶组件的东西,就像您在原始问题中提出的那样。我做了类似的事情——尽管没有使用 redux——as outlined in this gist。

引用Tom Coleman对github问题的回复:

在突变中包含加载状态并没有什么意义 容器;如果您考虑一下,您可以两次调用突变 同时——应该将哪个加载状态传递给孩子?我的 感觉一般来说混合命令式并不好(this.mutate(x,y,z)) 带有声明性(道具)的东西;它会导致无法解决的不一致。

【讨论】:

Tom 关于能够发送多个突变的解释是有道理的。并且 +1 用于您的要点中的替代 HOC 解决方案。我会将其标记为已接受。

以上是关于如何使用 react-apollo graphql 确定突变加载状态的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 react-apollo 使用相同的查询进行多个 graphql 查询?

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL

如何使用 react-apollo graphql 确定突变加载状态

如何在 react-apollo graphql 查询中正确使用动态变量?

Graphql,react-apollo如何在加载组件状态时将变量传递给查询

ReactJS/Javascript/Graphql/React-apollo:传递查询变量