停止重新渲染组件的 useMutation 并忽略结果
Stop `useMutation` from re-rendering component and ignore result
我有一个这样调用的突变(这不是实际的突变调用,而是一个最小的例子):
const App = () => {
const [myMutation] = useMutation(gql`
mutation Test($updateUserId: ID!, $updateUserInput: UpdateUserInput!) {
updateUser(id: $updateUserId, input: $updateUserInput) {
id
firstname
age
}
}
`);
// Runs every time this component is rendered
console.log("rendered");
// Called when the button is clicked
const update = () => {
myMutation({
variables: {
updateUserId: 1,
updateUserInput: {
age: Math.round(Math.random() * 10 + 5) // Set a random age from 5 - 15
}
}
});
};
return (
<>
<h1>Update Test</h1>
<button onClick={update}>Update!</button>
</>
);
};
每当调用 onClick
时,都会重新渲染整个组件。这不是我想要的,因为我不关心突变的结果。有什么方法可以阻止 myMutation
导致重新渲染,并完全忽略结果吗?
这可能是因为变异是 return 规范化对象,该组件或更高组件通过像 useQuery 这样的钩子依赖该对象。
如果您不关心突变的结果,请确保它不是 return 规范化对象。
类似
mutation SomeMutation ($input: SomeMutationInput!){
someMutation (input: $input){
ok
}
}
useMutation
是一个钩子,其中有 state
导致重新渲染
请参阅下面的 useMultation
类型:
export interface MutationResult<TData = any> {
data?: TData | null;
error?: ApolloError;
loading: boolean;
called: boolean;
client: ApolloClient<object>;
}
loading
状态是导致重新渲染的状态,因此您在哪个组件中删除 useMutation
它会因此重新渲染 state
一个可能的修复方法是将带有 useMutation
的组件与另一个
分开
像这样:
function App() {
return (
<>
<Header /> // <-- this coponent won't re-render
<UpdateUserButton /> // <-- useMutation is in here!
</>
);
}
检查现场示例:
嗯,如果你不需要突变返回的data
,你也可以传递ignoreResults
选项。数据不会从变异挂钩返回,但 loading
两者都不会调用,这会阻止重新渲染。
https://www.apollographql.com/docs/react/data/mutations/#ignoreresults
const [someMutation] = useSomeMutation({
ignoreResults: true,
});
以下应该有效(未测试)
- 由于您不想重新渲染,因此不需要使用具有状态的 useMutation 挂钩。
- 相反,您可以直接导入 apollo-client 并在其上使用 mutate,而无需使用 useMutation 挂钩。
- 您可以选择在 .then 函数中使用结果或删除它。
import { apolloClient } from '../yourApolloClientFile';
const App = () => {
const myMutation = (vars) => apolloClient.mutate({
mutation: gql`
mutation Test($updateUserId: ID!, $updateUserInput: UpdateUserInput!) {
updateUser(id: $updateUserId, input: $updateUserInput) {
id
firstname
age
}
}
`,
variables: vars
})
.then(result => console.log(result))
.catch(error => console.log(error))
// Runs every time this component is rendered
console.log("rendered");
// Called when the button is clicked
const update = () => {
myMutation({
updateUserId: 1,
updateUserInput: {
age: Math.round(Math.random() * 10 + 5) // Set a random age from 5 - 15
}
});
};
return (
<>
<h1>Update Test</h1>
<button onClick={update}>Update!</button>
</>
);
};
我有一个这样调用的突变(这不是实际的突变调用,而是一个最小的例子):
const App = () => {
const [myMutation] = useMutation(gql`
mutation Test($updateUserId: ID!, $updateUserInput: UpdateUserInput!) {
updateUser(id: $updateUserId, input: $updateUserInput) {
id
firstname
age
}
}
`);
// Runs every time this component is rendered
console.log("rendered");
// Called when the button is clicked
const update = () => {
myMutation({
variables: {
updateUserId: 1,
updateUserInput: {
age: Math.round(Math.random() * 10 + 5) // Set a random age from 5 - 15
}
}
});
};
return (
<>
<h1>Update Test</h1>
<button onClick={update}>Update!</button>
</>
);
};
每当调用 onClick
时,都会重新渲染整个组件。这不是我想要的,因为我不关心突变的结果。有什么方法可以阻止 myMutation
导致重新渲染,并完全忽略结果吗?
这可能是因为变异是 return 规范化对象,该组件或更高组件通过像 useQuery 这样的钩子依赖该对象。
如果您不关心突变的结果,请确保它不是 return 规范化对象。
类似
mutation SomeMutation ($input: SomeMutationInput!){
someMutation (input: $input){
ok
}
}
useMutation
是一个钩子,其中有 state
导致重新渲染
请参阅下面的 useMultation
类型:
export interface MutationResult<TData = any> {
data?: TData | null;
error?: ApolloError;
loading: boolean;
called: boolean;
client: ApolloClient<object>;
}
loading
状态是导致重新渲染的状态,因此您在哪个组件中删除 useMutation
它会因此重新渲染 state
一个可能的修复方法是将带有 useMutation
的组件与另一个
像这样:
function App() {
return (
<>
<Header /> // <-- this coponent won't re-render
<UpdateUserButton /> // <-- useMutation is in here!
</>
);
}
检查现场示例:
嗯,如果你不需要突变返回的data
,你也可以传递ignoreResults
选项。数据不会从变异挂钩返回,但 loading
两者都不会调用,这会阻止重新渲染。
https://www.apollographql.com/docs/react/data/mutations/#ignoreresults
const [someMutation] = useSomeMutation({
ignoreResults: true,
});
以下应该有效(未测试)
- 由于您不想重新渲染,因此不需要使用具有状态的 useMutation 挂钩。
- 相反,您可以直接导入 apollo-client 并在其上使用 mutate,而无需使用 useMutation 挂钩。
- 您可以选择在 .then 函数中使用结果或删除它。
import { apolloClient } from '../yourApolloClientFile';
const App = () => {
const myMutation = (vars) => apolloClient.mutate({
mutation: gql`
mutation Test($updateUserId: ID!, $updateUserInput: UpdateUserInput!) {
updateUser(id: $updateUserId, input: $updateUserInput) {
id
firstname
age
}
}
`,
variables: vars
})
.then(result => console.log(result))
.catch(error => console.log(error))
// Runs every time this component is rendered
console.log("rendered");
// Called when the button is clicked
const update = () => {
myMutation({
updateUserId: 1,
updateUserInput: {
age: Math.round(Math.random() * 10 + 5) // Set a random age from 5 - 15
}
});
};
return (
<>
<h1>Update Test</h1>
<button onClick={update}>Update!</button>
</>
);
};