web-dev-qa-db-ja.com

react-apolloggraphqlを使用してミューテーションのロード状態を判別する方法

2018更新:Apollo Client 2.1は、loadingプロパティを追加する新しいMutationコンポーネントを追加しました。以下の@ robin-wieruchの回答とここでの発表を参照してください https://dev-blog.apollodata.com/introducing-react-apollo-2-1-c837cc23d926 元の質問を読んでください。以前のバージョンのApolloに適用されます。


react-apollo (v0.5.2)のgraphql高階コンポーネントの現在のバージョンを使用すると、UIに次のことを通知する文書化された方法が表示されません。ミューテーションはサーバーの応答を待っています。 以前のバージョンのパッケージ がロードを示すプロパティを送信することがわかります。

ここに記載されているように、クエリは引き続き読み込みプロパティを受け取ります: http://dev.apollodata.com/react/queries.html#default-result-props

私のアプリケーションもreduxを使用しているので、それを行う1つの方法は、コンポーネントを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に通知するための、より慣用的なアプローチがあるかどうか知りたいです。ありがとう。

14
rmarscher

私は再投稿しました githubのこの質問 そして提案された解決策はあなたが元の質問で提案したのと同じように高次の反応コンポーネントのようなものを使用することでした。私は同様のことをしました–しかし、reduxを使用せずに– この要点で概説されているように

引用するには Tom Coleman githubの問題からの応答:

ミューテーションコンテナにロード状態を含めることは実際には意味がありません。あなたがそれについて考えるならば、あなたは同時に2回突然変異を呼ぶことができます-どの負荷状態が子供に受け継がれるべきですか?私の気持ちは、一般的に、命令型(this.mutate(x、y、z))と宣言型(props)のものを組み合わせるのはいいことではありません。それは解決できない矛盾につながります。

2
ctavan

Apollo Client 2.1 クエリとミューテーション コンポーネントのrender props関数 でこれらのプロパティにアクセスできるので、この質問に出くわした人は誰でも。

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 Client2.1リリースのブログ投稿から抜粋したサンプルコード。

5
Robin Wieruch