我的目标是在单击updateMutation
的按钮后,自动更新和显示{data.contact.contactInformation}
的新数据。然而,它只有在我刷新页面时才起作用。根据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;
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()
Apollo使用id
和__typename
生成缓存密钥。因此,具有1
的id
的用户和具有1
的id
的Post将不会共享同一密钥——它们的密钥将分别为User:1
和Post:1
。如果您的user
字段和updateContactDetails
返回不同的类型(即使这些类型具有完全相同的字段(,它们最终将使用不同的缓存键,因此Apollo将不知道需要更新user
查询。这应该在后端修复(即确保两个字段的类型相同(——如果无法修复,则需要通过向useMutation
挂钩提供update
函数来手动更新缓存。