0

我的目标是{data.contact.contactInformation}自动更新和显示新数据,一旦我单击updateMutation. 但是,它仅在我刷新页面后才有效。据我了解,根据Apollo 数据突变文档,必须返回 ID,然后由 Apollo 处理其余部分。

但我的代码似乎有一些错误。你知道它有什么问题吗?

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;

架构.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()
4

1 回答 1

0

Apollo 使用id__typename来生成缓存键。因此,具有 of 的 User 和具有idof的1Post将不会共享相同的密钥——他们的密钥将分别是和。如果您的字段和您返回的类型不同(即使这些类型具有完全相同的字段),它们最终会得到不同的缓存键,因此 Apollo 不会知道它需要更新查询。这应该在后端修复(即确保两个字段具有相同的类型)——如果无法修复,您需要通过向您的钩子提供一个函数来手动更新缓存。id1User:1Post:1userupdateContactDetailsuserupdateuseMutation

于 2020-02-29T23:42:33.040 回答