updateMutation不会更新数据

问题描述 投票:0回答:1

我的目标是,一旦我单击updateMutation的按钮,就会自动为{data.contact.contactInformation}更新和显示新数据。但是,只有刷新页面后它才起作用。据我了解,必须返回ID,然后Apollo应该处理其余的ID:https://www.apollographql.com/docs/react/data/mutations/#updating-a-single-existing-entity

但是我的代码似乎有一些错误。您看到问题了吗?

const FEED_QUERY = gql`
  query Contact($id: Int!) {
    contact(id: $id) {
      id
      contactInformation
      belongsTo {
        id
        username
        email
      }
    }
  }
`;

const UPDATE_CONTACT_DETAILS = gql`
  mutation updateContactDetails($contactInformation: String!) {
    updateContactDetails(contactInformation: $contactInformation) {
      id
      contactInformation
      belongsTo {
        id
        username
        email
      }
    }
  }
`;

function EmergencyContact() {
  const params = useParams();
  const { loading, error, data } = useQuery(FEED_QUERY, {
    variables: { id: params.contactId }
  });
  const [updateContactDetails] = useMutation(UPDATE_CONTACT_DETAILS);
  const [value, setValue] = useState("");

  if (loading) return "Loading...";
  if (error) return `Error! ${error.message}`;

  return (
    <>
      <div key={data.contact.id}>
        {data.contact.contactInformation}
        <form
          onSubmit={e => {
            e.preventDefault();
            updateContactDetails({
              variables: {
                contactInformation: value
              }
            });
            setValue("");
          }}
        >
          <input value={value} onChange={e => setValue(e.target.value)} />
          <button type="submit">Update Contact Information</button>
        </form>
      </div>
    </>
  );
}

export default EmergencyContact;

schema.py

class ContactInformationType(DjangoObjectType):
    class Meta:
        model = ContactInformation


class Query(graphene.ObjectType):
    contact = graphene.Field(ContactInformationType, id=graphene.Int())
    contact_access_key = graphene.Field(
        ContactInformationType, access_key=graphene.String()
    )
    contact_informations = graphene.List(ContactInformationType)

    @staticmethod
    def resolve_contact_informations(parent, info, **kwargs):
        return ContactInformation.objects.all()

    @staticmethod
    def resolve_contact_access_key(parent, info, **kwargs):
        access_key = kwargs.get("access_key")

        if not access_key:
            return

        contact_info = ContactInformation.objects.filter(access_key=access_key).first()
        if info.context.user != contact_info.belongs_to:
            raise PermissionDenied()

        return contact_info

    @staticmethod
    @login_required
    def resolve_contact(parent, info, **kwargs):
        id = kwargs.get("id")
        if id is not None:
            contact_info = ContactInformation.objects.filter(belongs_to__pk=id).first()
            if info.context.user != contact_info.belongs_to:
                raise PermissionDenied()

            return contact_info


class UpdateContactDetails(graphene.Mutation):
    id = graphene.ID()
    contact_information = graphene.String()
    belongs_to = graphene.Field(UserType)

    class Arguments:
        contact_information = graphene.String()

    @staticmethod
    def mutate(self, info, contact_information):
        contact_detail = ContactInformation.objects.get(belongs_to=info.context.user)
        contact_detail.contact_information = contact_information
        contact_detail.save()
        return UpdateContactDetails(
            id=contact_detail.pk,
            contact_information=contact_detail.contact_information,
            belongs_to=contact_detail.belongs_to,
        )


class Mutation(graphene.ObjectType):
    update_contact_details = UpdateContactDetails.Field()
reactjs graphql react-apollo apollo-client graphene-django
1个回答
0
投票

Apollo同时使用id__typename生成缓存密钥。因此,具有id1的用户和具有id1的帖子将不会共享同一密钥-他们的密钥分别为User:1Post:1。如果user字段和updateContactDetails返回不同的类型(即使这些类型具有完全相同的字段),则它们将以不同的缓存键结尾,因此Apollo将不知道需要更新user查询。这应该在后端修复(即,确保两个字段具有相同的类型)-如果无法修复,则需要通过向update钩子提供useMutation函数来手动更新缓存。

© www.soinside.com 2019 - 2024. All rights reserved.