Reactjs 当我的useEffect挂钩在react apollo突变后触发时,如何解决react发出的警告?

Reactjs 当我的useEffect挂钩在react apollo突变后触发时,如何解决react发出的警告?,reactjs,graphql,apollo,react-apollo,react-hooks,Reactjs,Graphql,Apollo,React Apollo,React Hooks,我的UI中有一个“卡片”列表,在任何给定的时间只能扩展一张卡片。此列表有一个react apollo查询,它监视作业列表并返回一个标记下一个未完成作业的道具(nextJobId)。此道具由useffect挂钩跟踪,当nextJobId道具更新时,挂钩会更新扩展卡 每张卡中都有一个按钮,可以触发一个react apollo突变,它更新数据库(将job.done设置为true),然后更新nextJobId属性。一旦发生这种情况,包含刚才单击的按钮的卡就会折叠,并破坏该按钮 这似乎触发了以下错误: r

我的UI中有一个“卡片”列表,在任何给定的时间只能扩展一张卡片。此列表有一个
react apollo
查询,它监视作业列表并返回一个标记下一个未完成作业的道具(
nextJobId
)。此道具由
useffect
挂钩跟踪,当
nextJobId
道具更新时,挂钩会更新扩展卡

每张卡中都有一个按钮,可以触发一个
react apollo
突变,它更新数据库(将
job.done
设置为true),然后更新
nextJobId
属性。一旦发生这种情况,包含刚才单击的按钮的卡就会折叠,并破坏该按钮

这似乎触发了以下错误:

react-dom.development.js?61bb:507 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 the `componentWillUnmount` method.
我相信现在发生的是apollo缓存在变异完成之前被更新(如果我在
mutation
组件中添加
onCompleted
函数,它永远不会被触发)

这是钩子:

useffect(()=>{
client.writeData({
数据:{
openVisitId:nextJobId
}
})
},[nextJobId])
以下是突变:

mutation FinishJob($visitId: ID!) {
  updateJobInstance(data: { done: true }, where: { id: $visitId }) {
    done
    id
  }
}
到目前为止,我已经找到了两种解决方法:

1) 将
setTimeout
添加到挂钩:

useffect(()=>{
设置超时(()=>{
client.writeData({
数据:{
liveVisitId:nextJobId,
openVisitId:nextJobId
}
})
})
},[nextJobId])
不知道为什么会这样

2) 从突变中删除
done
(我相信这会绕过直接缓存更新),然后使用
refetchquerys
再次重新提取主列表:

mutation FinishJob($visitId: ID!) {
  updateJobInstance(data: { done: true }, where: { id: $visitId }) {
    id
  }
}
。。。

这让我想到缓存正在乐观地更新,这导致点击的按钮在变异实际完成之前被破坏。是这样吗?如果是这样的话,有没有办法告诉阿波罗在变异实际完成之前不要更新缓存?

这个警告的意思是你正在尝试更新未安装组件的状态。E.x您正在等待您的请求完成,然后将数据添加到状态,但请求耗时太长,您正在导航到另一个页面。但请求仍在完成,因此在完成后无法将其数据添加到状态

因此,为了防止它,最好使用
\u安装

function SomeName(){
    const _isMounted = false;

    useEffect(() => {
        _isMounted = true; //this is equivalent of componentDidMoun()
        return () => {
            _isMounted = false; //this is equivalent of componentWillUnmount()
        }
    }, [])
}
现在,每次需要更新状态时,都要检查它是否已装载,以便更新状态

if(_isMounted)
{
    this.setState({
        //your data
    })
}

此警告的意思是,您正在尝试更新未安装组件的状态。E.x您正在等待您的请求完成,然后将数据添加到状态,但请求耗时太长,您正在导航到另一个页面。但请求仍在完成,因此在完成后无法将其数据添加到状态

因此,为了防止它,最好使用
\u安装

function SomeName(){
    const _isMounted = false;

    useEffect(() => {
        _isMounted = true; //this is equivalent of componentDidMoun()
        return () => {
            _isMounted = false; //this is equivalent of componentWillUnmount()
        }
    }, [])
}
现在,每次需要更新状态时,都要检查它是否已装载,以便更新状态

if(_isMounted)
{
    this.setState({
        //your data
    })
}

Ok将
ignoreResults
添加到
组件似乎可以解决此问题(请参阅)。如果有更好的方法,我不会将其标记为已回答。好的,将
忽略结果
添加到
组件似乎可以解决此问题(请参阅)。我不会在回答之前标记它,以防有更好的方法。谢谢,有道理!这似乎更多地与孩子身上的
react apollo
突变
组件有关,而不是与父母身上的钩子有关-突变的孩子在完成之前就被摧毁了(我假设它正在使用引擎盖下的状态)。谢谢,这很有意义!这似乎更多地与孩子身上的
react apollo
突变
组件有关,而不是父母身上的钩子-发生突变的孩子在完成之前就被摧毁了(我假设它正在使用引擎盖下的状态)。