Iam building an app using react hooks
and apollo client 3
trying to update the state on useQuery
complete
here is the code
const GET_POST_BY_ID_QUERY = gql`
query getPostById($postId: ID!) {
getPostById(postId: $postId) {
id
title
body
}
}
`;
const [{ title, body }, setPost] = useState({ title: '', body: '' });
useQuery(GET_POST_BY_ID_QUERY, {
variables: { postId: route?.params?.postId },
skip: !route.params,
onCompleted: data => {
console.log('data', data.getPostById);
setPost(data.getPostById);
},
onError: err => {
console.log(err);
}
});
it keep on giving me this error
Warning: Can't perform a React state update on an unmounted component.
This is a no-op, but it indicates a memory leak in your application.
To fix, cancel all subscriptions and asynchronous tasks in %s.%s, a useEffect cleanup function
I am not using useEffect
at all within this screen.
What could be wrong ?
React is warning you that you're trying to update a stateful variable that's no longer there. What's probably happening is that your component is unmounted after your query has begun execution, but before it has actually completed. You can solve this by adding an if(mounted)
statement inside your onCompleted
handler to check if the component is still there, before trying to update its state.
However, I suggest you drop the onCompleted
and onError
callbacks and opt to the use variables as returned by the useQuery
hook. Your code will look like this:
const { data, loading, error } = useQuery(GET_POST_BY_ID_QUERY, {
variables: { postId: route?.params?.postId },
skip: !route.params
})
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<div>
<p>{data.getPostById.title}</p>
<p>{data.getPostById.body}</p>
</div>
)
The new approach with hooks allows you to simplify your code and handle the lifecycle of your component without having to wire a bunch of event handlers together. This way you can avoid many of the state-woes altogether.