警告:无法对未安装的组件执行 React 状态更新。在功能组件中

Posted

技术标签:

【中文标题】警告:无法对未安装的组件执行 React 状态更新。在功能组件中【英文标题】:Warning: Can't perform a React state update on an unmounted component. In a functional component 【发布时间】:2020-11-22 13:58:28 【问题描述】:

我有一个功能组件,我从我的 localStorage 中获取一个值并使用该值设置一个状态值:

localforage.getItem<string>('sortType').then((value) => 
  setSortType(value)
)

const [sortType, setSortType] = useState('release_date');

当我运行组件时,我会得到一个日志:

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

我读到发生这种情况是因为我在一个状态上使用了异步方法localforage.getItem。但我还没有找到适用于功能组件的解决方案。

【问题讨论】:

会不会是在设置状态之前先定义状态? 这能回答你的问题吗? Can't perform a React state update on an unmounted component 【参考方案1】:

您在 promise 解决后设置状态,这可能导致此代码在组件卸载后运行。

要解决这个问题,您可以在设置状态之前检查组件是否仍然挂载:

const isMountedRef = useRef(true)
useEffect(() => () =>  isMountedRef.current = false , [])

由于依赖数组为空,组件挂载时调用效果,卸载时执行回调

// somewhere in your code later
localforage.getItem<string>('sortType').then((value) => 
  if (isMountedRef.current) 
      setSortType(value)
  
)

【讨论】:

您能解释一下组件何时卸载吗?换句话说,何时调用 useEffect 挂钩,我看到它是在我更改组件中的某些内容之后。 我已经用解释更新了我的答案,希望对您有所帮助 当你可以调用localforage.getItem一次在useEffect中,那么,为什么我们需要检查mounted状态呢? 因为then 回调可能仍会在组件卸载后执行。 ***.com/questions/53949393/… 对我有帮助。在这里也 +1。【参考方案2】:

尝试使用 React.useEffect 从 localStorage 运行一次 sortType,如下所示:

const [sortType, setSortType] = useState('release_date');

React.useEffect(() => 
  localforage.getItem<string>('sortType').then((value) => 
    setSortType(value)
  )
, []);

【讨论】:

以上是关于警告:无法对未安装的组件执行 React 状态更新。在功能组件中的主要内容,如果未能解决你的问题,请参考以下文章

警告:无法对未安装的组件执行 React 状态更新。在功能组件中

“警告:无法对未安装的组件执行 React 状态更新。” [关闭]

警告:无法在 React 本机中对未安装的组件执行 React 状态更新

React-Apollo - 查询 - renderProp:反应警告:无法对未安装的组件执行反应状态更新

无法使用 fetch POST 方法对未安装的组件执行 React 状态更新

登录页面后反应路由器 v6 不会切换到主页:警告:无法对未安装的组件执行 React 状态更新