首页 文章

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

提问于
浏览
11

2018 Update: Apollo Client 2.1添加了一个新的Mutation组件,用于添加加载属性 . 请参阅下面的@ 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));

我很好奇是否有一种更惯用的方法来告知用户界面该变异是“在飞行中” . 谢谢 .

2 回答

  • 2

    任何偶然发现这个问题的人,因为Apollo Client 2.1你可以访问Query and Mutation组件的渲染道具功能中的那些属性 .

    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发布的博客文章 .

  • 4

    我已经重新发布了this question on github,建议的解决方案是使用像你在原始问题中提出的反应更高阶组件 . 我做了类似的事情 - 虽然没有使用redux - as outlined in this gist .

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

    在变异容器中包含加载状态实际上没有意义;如果你考虑一下,你可以同时调用两次突变 - 哪种加载状态应该传递给孩子?我的感觉一般来说,将命令式(this.mutate(x,y,z))与声明性(道具)事物混合起来并不好;它导致无法解决的不一致 .

相关问题