无法对未安装的组件执行 React 状态更新(useEffect 反应挂钩)
Posted
技术标签:
【中文标题】无法对未安装的组件执行 React 状态更新(useEffect 反应挂钩)【英文标题】:Can't perform a React state update on an unmounted component (useEffect react hooks) 【发布时间】:2020-08-02 23:51:24 【问题描述】:我正在使用以下代码(useEffect)来更改滚动类。
import useState, useEffect from "react"
export const useScrollHandler = () =>
// setting initial value to true
const [scroll, setScroll] = useState(1)
// running on mount
useEffect(() =>
const onScroll = () =>
const scrollCheck = window.scrollY < 10
if (scrollCheck !== scroll)
setScroll(scrollCheck)
// setting the event handler from web API
document.addEventListener("scroll", onScroll)
// cleaning up from the web API
return () =>
document.removeEventListener("scroll", onScroll)
, [scroll, setScroll])
return scroll
即使我使用了清理功能,当我执行 history.push("/") 时也会出现以下错误
警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。
如何解决?
这里我使用了useScrollHandler。
function HomeNav()
const scroll = useScrollHandler()
return (
<React.Fragment>
<nav
className=
scroll ? "navbar navbar-expand-lg navbar-light fixed-top py-3" : "navbar navbar-expand-lg navbar-light fixed-top py-3 navbar-scrolled"
id="mainNav"
>
</nav>
</React.Fragment>
)
export default HomeNav
【问题讨论】:
为什么在 useEffect 的第二个 args 数组中将setScroll
作为依赖项?另外,你可以在你使用useScrollHandler
的地方添加代码吗?
您要删除unmount
上的eventListener
吗?
@SarthakAggarwal 是的。
【参考方案1】:
试试这个来删除unmount
上的EventListener
。
const onScroll = () =>
const scrollCheck = window.scrollY < 10
if (scrollCheck !== scroll)
setScroll(scrollCheck)
useEffect(() =>
// Add event listener on component mount
document.addEventListener("scroll", onScroll)
// removing event listener on component unmount
return () =>
document.removeEventListener("scroll", onScroll)
, []) // This useEffect will act as componentDidMount and return function as componentWillUnmount as no dependencies are given.
【讨论】:
【参考方案2】:我认为您在事件处理程序中不需要scroll
,并且保证setScroll
保持不变,这意味着您的效果处理程序可以使用[]
作为其依赖数组。
简化这可能会有所帮助。
import useState, useEffect from "react"
export const useScrollHandler = () =>
// setting initial value to true
const [scroll, setScroll] = useState(true);
// running on mount
useEffect(() =>
const onScroll = () => setScroll(window.scrollY < 10)
// setting the event handler from web API
document.addEventListener("scroll", onScroll)
// cleaning up from the web API
return () =>
document.removeEventListener("scroll", onScroll)
, [])
return scroll
【讨论】:
以上是关于无法对未安装的组件执行 React 状态更新(useEffect 反应挂钩)的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 fetch POST 方法对未安装的组件执行 React 状态更新