簡體   English   中英

如何在頁面加載時設置 useState 掛鈎的 state?

[英]How to set the state of a useState hook on page load?

我正在嘗試創建一個響應式導航。 它有一個 _ 功能:

  1. 在頁面加載時在屏幕寬度 > 768px 上顯示導航鏈接
  2. 頁面加載時屏幕寬度 < 768px 不顯示導航鏈接
  3. 如果在切換到大屏幕時在小屏幕上未打開,則關閉導航(簡單地說,如果用戶在移動設備上打開導航鏈接,切換到更大的屏幕尺寸,然后返回移動設備,導航鏈接應該再次隱藏)

我完成了 99% 的工作,但我認為我這樣做是因為當我在較小的屏幕上時,導航會在短時間內鏈接 flash,然后消失。 這顯然不是我想要的。

下面是一個精簡的、非樣式化的代碼段,以便於調試:

export const Nav = () => {
  const [showNavOnClick, setShowNavOnClick] = useState(false)
  const [hamburgerOpen, setHamburgerOpen] = useState(false)
  const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(true)

  const toggleMenu = () => {
    setShowNavOnClick(!showNavOnClick)
    setHamburgerOpen(!hamburgerOpen)
  }

  useEffect(() => {
    // This line solves all 3 goals, but on page load, the nav links appear, then dissapear in a split moment. 
    if (window.innerWidth < 768) setShowNavOnScreenSize(false)

    const handleResize = () => {
      if (window.innerWidth > 768) {
        setShowNavOnScreenSize(true)
        setShowNavOnClick(false)
      } else if (window.innerWidth < 768) {
        setShowNavOnScreenSize(false)
      }
    }

    window.addEventListener('resize', handleResize)

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

  return (
    <nav>
      <a href="/">Home</a>
      <button onClick={toggleMenu}>*</button>
      <a
        href="/about"
        className={`${
          showNavOnScreenSize ||
          showNavOnClick && showNavOnScreenSize != showNavOnClick)
            ? 'visible'
            : 'hidden'
        }`}>
        About
      </a>
    </nav>
  )
}

以下是顯示故障的視頻:

在此處輸入圖像描述

當我添加const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(window.innerWidth >= 768)時,我收到window is not defined的錯誤

在此處輸入圖像描述

您可以通過更改 state 的默認值來解決此問題,該值是根據寬度計算的,而不是硬編碼的true

const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(window.innerWidth >= 768)

如有必要,您可以以類似的方式為其他狀態設置默認值。

編輯:或者,嘗試使用布局效果,以便重新渲染是同步的:

const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(true)

useLayoutEffect(() => {
    if (window.innerWidth < 768) setShowNavOnScreenSize(false)
    // ...

暫無
暫無

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

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