簡體   English   中英

當我在 React 掛鈎中添加 Nextjs Image 組件時,將顯示錯誤“無法對未安裝的組件執行 React state 更新。”

[英]When I add Nextjs Image component in react hook, will show error "Can't perform a React state update on an unmounted component."

當 window 寬度改變時,我制作了一個需要改變布局的 UI。

但是當我在鈎子中添加 Image(Nextjs component) 時,我會收到錯誤消息。

不知道為什么add Image(Nextjs component)會出現這個問題。

Devtool 顯示錯誤信息。

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 a useEffect cleanup function.
    at Image (webpack-internal:///./node_modules/next/dist/client/image.js:376:22)
    at a
    at div
    at div
    at LinkBar

鈎子有問題

const LinkBar = () => {
  return (
    <>
      <div className="justify-center items-center flex flex-wrap gap-4">
        <a target="_blank" href="https://www.twitch.tv/xxxxxx" rel="noopener noreferrer">
          <div className="px-4 rounded-lg border-2 border-blue-200 bg-purple-400 ring-2 ring-purple-900 font-bold hover:text-white">
            Twitch
          </div>
        </a>
      </div><div className="mt-4 gap-4 md:flex md:justify-center md:items-center">
        <div className="text-center">
          <a target="_blank" href="xxxxxx" rel="noopener noreferrer">
            <Image src="/images/line_stamp.jpg" alt="logo" width={320} height={240} layout="intrinsic" />
          </a>
        </div>
        <div className="text-center">
          <SubscriptionStampViewer />
        </div>
        <div className="py-4"></div>
      </div>
    </>
  )
}

檢查寬度為 function 的主頁。

const Home: NextPage = () => {
  const [mobileStyle, setMobileStyle] = useState(false);

  const handleResize = () => {
    if (window.innerWidth > 767) {
      setMobileStyle(true);
    } else if (window.innerWidth < 767) {
      setMobileStyle(false);
    }
  }

  useEffect(() => {
    handleResize();

    window.addEventListener('resize', handleResize);

    return () => window.removeEventListener('resize', handleResize);
  }, [])

  return (
    <Layout>
      <div className="w-full">
        <div className="justify-center items-end md:flex">
          <div className="px-4 pt-4 md:p-0 md:mb-16">
            <div>
              <Image src="/images/logo.png" alt="logo" width={750} height={264} layout="intrinsic" />
            </div>
            {mobileStyle ? <LinkBar /> : null}
          </div>
          <div className="text-center">
            <Image src="/images/avatar.png" alt="avatar" width={666} height={850} layout="intrinsic" />
          </div>
          {mobileStyle ? null : <LinkBar />}
        </div>
      </div>
    </Layout>
  )
}

SubscriptionStampViewer 代碼

const SubscriptionStampViewer = () => {
    const [toggle, setToogle] = useState(true);

    return (
        <div className="border-2 w-80 h-60">
            <div className="h-4/5 border-2 overflow-auto">
                <div>Follow</div>
                <div>Tier1</div>
                <div>Tier2</div>
                <div>Tier3</div>
                <div>Bits</div>
            </div>
            <div className="h-1/5 border-2 flex">
                {toggle ?
                    <>
                        <button className="w-1/2 h-full bg-red-500 hover:bg-red-500 active:bg-red-900" disabled={toggle} onClick={e => setToogle(true)}>Sub</button>
                        <button className="w-1/2 h-full bg-green-200 hover:bg-green-500 active:bg-green-900" onClick={e => setToogle(false)}>Badges</button>
                    </>
                    :
                    <>
                        <button className="w-1/2 h-full bg-red-200 hover:bg-red-500 active:bg-red-900" onClick={e => setToogle(true)}>Sub</button>
                        <button className="w-1/2 h-full bg-green-500 hover:bg-green-500 active:bg-green-900" disabled={!toggle} onClick={e => setToogle(false)}>Badges</button>
                    </>
                }


            </div>
        </div>
    )
}

我認為您可以將代碼更改為以下

useEffect(() => {
  // try adding this
  if (typeof window !== 'undefined') {
     handleResize();
  }

  window.addEventListener('resize', handleResize);

  return () => window.removeEventListener('resize', handleResize);
}, [])

return (
  <Layout>
    <div className="w-full">
      <div className="justify-center items-end md:flex">
        <div className="px-4 pt-4 md:p-0 md:mb-16">
          <div>
            <Image src="/images/logo.png" alt="logo" width={750} height={264} layout="intrinsic" />
          </div>
          {mobileStyle && <LinkBar />}
        </div>
        <div className="text-center">
          <Image src="/images/avatar.png" alt="avatar" width={666} height={850} layout="intrinsic" />
        </div>
        {!mobileStyle && <LinkBar />}
      </div>
    </div>
  </Layout>
)

SubscriptionStampViewer中,為了減少重復,您可以將代碼更改為:

<div className="h-1/5 border-2 flex">
  <button className={`w-1/2 h-full bg-red-${toggle ? "500" : "200"} hover:bg-red-500 active:bg-red-900`} disabled={toggle} onClick={e => setToogle(true)}>Sub</button>
  <button className={`w-1/2 h-full bg-green-${toggle ? "200" : "500"} hover:bg-green-500 active:bg-green-900`} disabled={!toggle} onClick={e => setToogle(false)}>Badges</button>
</div> 

暫無
暫無

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

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