提问者:小点点

无法对未安装的组件执行反应状态更新(useEffect React挂钩)


我正在使用以下代码(useEffect)更改scroll上的类。

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
}

即使我使用了cleanup函数,当我执行历史记录时也会出现以下错误。推送(“/”)

警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务。

怎么解决呢?

这里我使用了UseCollHandler。

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

共2个答案

匿名用户

尝试在卸载上删除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.


匿名用户

我认为您不需要在事件处理程序中使用滚动,并且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
}