簡體   English   中英

無法對未安裝的組件執行 React state 更新(useEffect 反應掛鈎)

[英]Can't perform a React state update on an unmounted component (useEffect react hooks)

我正在使用以下代碼(useEffect)在滾動時更改 class。

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
}

即使我使用清理 function 它在我執行 history.push("/") 時也會出現以下錯誤

警告:無法對未安裝的組件執行 React state 更新。 這是一個無操作,但它表明您的應用程序中存在 memory 泄漏。 要修復此問題,請在 useEffect 清理 function 中取消所有訂閱和異步任務。

如何解決?

這里我使用了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

試試這個在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.


我認為您不需要在事件處理程序中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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM