[英]QueryRenderer doesn't update after a mutation is committed
我对中继和 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, onCompleted, onError }) => {
const variables = { userId, animalId }
commitMutation(environment, {
mutation,
variables,
onCompleted,
onError
})
}
有什么明显的我做错了吗? 如您所见,有一个嵌套的 QueryRenderer HOC,这是否会以某种方式破坏自动更新?
我没有使用订阅,因为我不需要实时事件监听。 仅当用户添加新宠物时才会更新此数据,并且这种情况不会经常发生。 而且我没有使用乐观更新/响应,因为在等待响应之前实际上不需要向用户显示更新成功。
从文档看来,有一种方法可以使用 Refetch Container 来做到这一点,但是必须重构我的代码才能使用片段。
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()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.