useQuery onCompleted之后更新状态...错误

时间:2020-10-20 21:44:22

标签: react-native apollo react-apollo apollo-client use-state

我使用react hooksapollo client 3构建应用程序

尝试在useQuery完成时更新状态

这是代码

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);
    }
  });

它继续给我这个错误

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

在此屏幕上,我根本没有使用useEffect

怎么了?

1 个答案:

答案 0 :(得分:0)

React 警告您,您正在尝试更新不再存在的有状态变量。可能发生的情况是您的组件在您的查询开始执行之后,但在它实际完成之前被卸载。您可以通过在 if(mounted) 处理程序中添加 onCompleted 语句来解决此问题,以便在尝试更新其状态之前检查组件是否仍然存在。

不过,我建议您放弃 onCompletedonError 回调并选择 use variables as returned by the useQuery hook。您的代码将如下所示:

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 允许您简化代码并处理组件的生命周期,而无需将一堆事件处理程序连接在一起。这样您就可以完全避免许多状态问题。