1

リレーを介してプレーン配列でミューテーションを行う方法を理解するのに苦労しています。

投稿に新しいタグを追加しようとしています。サーバー側で正常に追加された後、クライアント側で更新されません。

新しいタグを表示するには、手動でリロードする必要があります。と の両方を試しましREQUIRED_CHILDRENthis.props.relay.forceFetch()が、役に立ちませんでした。

また、投稿を試みFIELDS_CHANGEました。

GraphQL スキーマ:

Post {
  id: ID!
  text: String!
  tags: [Tag!]!
}

Tag {
  id: ID!
  name: String!
}

AddTagToPostMutation:

  static fragments = {
    post: () => Relay.QL`
      fragment on Post {
        id
        tags
      }
    `,
  }

  getMutation() {
    return Relay.QL`mutation { addTagToPost }`;
  }

  getVariables() {
    return {
      name: this.props.tag.name,
    };
  }

  getFatQuery() {
    return Relay.QL`
      fragment on AddTagToPostMutationPayload {
        tag {
          id
          name
        }
        post {
          id
          tags
        }
      }
    `;
  }

  getConfigs() {
    return [{
      type: 'REQUIRED_CHILDREN',
      children: [Relay.QL`
        fragment on AddTagToPostMutationPayload {
          tag {
            id
            name
          }
          post {
            id
            tags
          }
        }
      `],
    }];
  }

  getOptimisticResponse() {
    return {
      tag: {
        name: this.props.tag.name,
      },
      post: {
        id: this.props.post.id,
      },
    };
  }
4

2 に答える 2

3

freiksenet が既に指摘したように、関数FIELDS_CHANGEで使用する必要がありgetConfigs()ます。私はあなたのスキーマを取り、GraphQL タイプ、サーバー側とクライアント側のミューテーションを実装して、投稿にタグを追加しました。クライアント側は正常に更新されます。私の答えで解決策を詳しく説明します。

まず、サーバー側のミューテーションを確認します。私の実装では、 graphqlおよびgraphql-relayライブラリを使用しており、以下のようになっています。サーバー側のミューテーションの出力は、タグが追加された投稿であることに注意してください。この投稿は、入力として ID が提供された投稿です。

const AddTagToPostMutation = mutationWithClientMutationId({
  name: 'AddTagToPost',
  inputFields: {
    postId: { type: new GraphQLNonNull(GraphQLID) },
    name: { type: new GraphQLNonNull(GraphQLString) },
  },
  outputFields: {
    post: {
      type: PostType,
      resolve: ({id}) => getPost(id),
    },
  },
  mutateAndGetPayload: ({postId, name}) => {
    const id = fromGlobalId(postId).id;
    addTagToPost(id, name);
    return {id};
  },
});

graphiqlを使用して、ミューテーションをテストできます。

mutation {
  addTagToPost(input:{
      postId: "UG9zdDpwb3N0Mg==" 
      name:"a new tag name" 
      clientMutationId:"123244"}) {
    post {
      id
      text
      tags {
        id
        name
      }
    }
  }
}

すべての投稿のフィールドpostsをルート クエリに追加しました。graphiqlを使用して、最初に投稿 ID を確認し、上記のものを使用しました。

react-relayを使用すると、クライアント側のミューテーション コードは次のようになります。postID が関数の入力変数として使用されるprop が渡されgetVariables()ます。getConfigs()関数では、フィールドを更新する必要があることを指定しますpost。ペイロード フィールドpostと渡された prop の間の関連付けは、ミューテーション タイプpostを使用して確立されます。FIELDS_CHANGE

export default class AddTagToPostMutation extends Relay.Mutation {
  getMutation() {
    return Relay.QL`mutation{addTagToPost}`;
  }

  getVariables() {
    return {
      postId: this.props.post.id,
      name: this.props.name,
    };
  }

  getFatQuery() {
    return Relay.QL`
      fragment on AddTagToPostPayload {
        post {
          id,
          tags {
            id,
            name,
          }
        }
      }
    `;
  }

  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {
        post: this.props.post.id,
      },
    }];
  }

  static fragments = {
    post: () => Relay.QL`
      fragment on Post {
        id,
      }
    `,
  };
}

クライアント側のミューテーションは次のように呼び出されます。

Relay.Store.commitUpdate(new AddTagToPostMutation({
      post: postToModify,
      name: tagName,
    }));
于 2016-04-14T10:06:44.543 に答える
1

そのような状況では FIELDS_CHANGE を使用するだけでよいと思います。

  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {post: this.props.post.id},
    }];
  }

  getOptimisticResponse() {
    return {
      post: {
        id: this.props.post.id,
        tags: [...this.props.post.tags, this.props.tag],
      },
    };
  }
于 2016-04-13T10:50:15.267 に答える