如何解决提交突变后,QueryRenderer不会更新
我对中继和GraphQL还是很陌生,希望模仿添加突变后的行为,我的组件会使用新突变进行更新。例如,当我添加动物时,它会显示在我的动物列表中。
我已经阅读了一些有关通过乐观更新,获取容器等手动更新商店的信息,但是想知道是否仅通过使用QueryRenderer HOC和简单的突变就可以发生这种行为。
该变异成功完成,但是刷新页面后我才能看到更新。
export const Customer = ({ userId }) => {
return (
<QueryRenderer
environment={environment}
query={query}
variables={{ userId }}
render={({ error,props }) => {
//handle errors and loading
const user = props.customers_connection.edges[0].node
return (
<div className="flex justify-between items-center">
<h1 className="text-xl">Pets</h1>
<AddPetForm />
<PetList user={user} />
</div>
)
}}
/>
)
}
const query = graphql`
query CustomerQuery($userId: bigint) {
customers_connection(where: { userId: { _eq: $userId } }) {
edges {
node {
id
userId
pets {
id
animal {
...Animal_animal
}
}
}
}
}
}
`
这里是Animal
组件中的PetList
组件。 PetList
组件是我希望重新渲染的组件,它将包括一个新的Animal
组件,其中包含通过突变创建的动物。
const Animal = ({ animal }) => {
return (
<li>
<Summary animal={animal} />
</li>
)
}
export default createFragmentContainer(Animal,{
animal: graphql`
fragment Animal_animal on animals {
name
category
imageUrl
weight
type
}
`
})
这是AddPetForm
组件:
const AddPetForm = () => {
const { hide } = useModal()
return (
<Modal>
<QueryRenderer
environment={environment}
query={query}
variables={{}}
render={({ error,props }) => {
//handle errors and loading
return (
<Form
hide={hide}
//pass down props from query
/>
)
}}
/>
</Modal>
)
}
const query = graphql`
query AddPetFormQuery {
enum_animal_category_connection {
edges {
node {
id
value
}
}
}
//other enums to use in the form
}
`
以及用于突变的代码(该代码位于AddPetForm
组件中):
const Form = ({ hide,...other props }) => {
const { handleSubmit,register,errors,} = useForm({ defaultValues,resolver })
const [mutationIsInFlight,setMutationIsInFlight] = useState(false)
const [mutationHasError,setMutationHasError] = useState(false)
const onCompleted = (response,error) => {
setMutationIsInFlight(false)
if (error) onError(error)
else showSuccessNotification()
}
const onError = error => {
setMutationIsInFlight(false)
setMutationHasError(true)
}
const onSubmit = animal => {
setMutationIsInFlight(true)
setMutationHasError(false)
//assume animal has already been added
addAnimalAsPet({ animalId: animal.animalId,userId,onCompleted,onError })
}
return (
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-wrap">
// all of the inputs
<div className="mt-3 w-full">
<PrimaryButton type="submit" fullWidth={true} loading={mutationIsInFlight}>
Save
</PrimaryButton>
</div>
{mutationHasError && <p className="text-red-700 my-3">An error has occurred. Please try again.</p>}
</form>
)
}
以及突变代码:
const mutation = graphql`
mutation addAnimalAsPet Mutation($animalId: Int,$userId: Int) {
insert_pets_one(object: { animalId: $animalId,userId: $userId }) {
id
}
}
`
export const addAnimalAsPet = ({ userId,animalId,onError }) => {
const variables = { userId,animalId }
commitMutation(environment,{
mutation,variables,onError
})
}
有什么明显的地方我做错了吗?如您所见,有一个嵌套的QueryRenderer HOC,这会以某种方式破坏自动更新吗?
我没有使用订阅,因为我不需要实时事件监听。仅当用户添加新宠物时,才会更新此数据,并且这种情况不会经常发生。而且我还没有使用过乐观的更新/响应,因为在等待响应之前并不需要真正向用户展示更新是否成功。
从文档中看,似乎有一种方法可以使用“ Refetch容器”来实现,但是必须重构我的代码才能使用片段。
解决方法
xadm的建议很吸引人。有一个retry
函数是QueryRenderer
render
道具中对象的属性。
这是一个可行的示例:
<QueryRenderer
environment={environment}
query={query}
variables={{ userId }}
render={({ error,props,retry }) => {
//handle errors and loading
const user = props.customers_connection.edges[0].node
return (
<div className="flex justify-between items-center">
<h1 className="text-xl">Pets</h1>
<AddPetForm refreshCustomerQuery={retry} />
<PetList user={user} />
</div>
)
}}
/>
然后在成功成功突变后,我就简单地调用refreshCustomerQuery
函数。
const onCompleted = (response,error) => {
setMutationIsInFlight(false)
if (error) onError(error)
else {
showSuccessNotification()
refreshCustomerQuery()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。