簡體   English   中英

在 React 中使用 state 的正確方法

[英]Correct way to use state in React

更新:

所以我試圖弄清楚,但不能。 我有一個觸發切換導航欄 function 的toggleNavbar

我還有windowResized function 檢查瀏覽器是否寬於 576。如果該條件為真,則檢查navbarState是否為真。 如果兩個條件都為真,則應從toggleNavbar function 調用windowResized function。

我遇到的問題是下面的 if 語句( windowResized函數中的那個)永遠不會運行,因為 state 沒有更新。

if (navbarState) {
  toggleNavbar()
}

有沒有辦法在我進行檢查之前確保 navbarState 更新?

導航欄.js

import React, { useState, useRef, useEffect } from "react"
import { Link } from "gatsby"
import styles from "./styling/navbar.module.less"

const Navbar = ( props ) => {

  const [navbarState, setNavbarState] = useState(false)
  const [navHeight, setNavHeight] = useState()
  const ref = useRef(null)

  useEffect(() => {
    let windowResized = () => {
      let windowWidth = window.innerWidth
      if (windowWidth > 576) {
        if (navbarState) {
          toggleNavbar()
        }
      }
    }
    window.addEventListener('resize', windowResized)

    setNavHeight(ref.current.clientHeight)
  }, [])

  let toggleNavbar = () => {
    setNavbarState((navbarState) => !navbarState)
    if (navbarState) {
      props.updateClassNames(styles.contentLeftAnimate)
    }
    else{
      props.updateClassNames(styles.contentRightAnimate)
    }
  }
    
  return (
    <nav ref={ref} id={"navigation-bar"}>
      <div className={`${styles.navLinks} ${navbarState? styles.navActive:""}`} 
      style={{top: `${navHeight}px`}}>
        {props.pages.map((page, index) => (
          <Link key={page.name} className={`${styles.navLink} ${styles.navLinkHoverEffect} ${navbarState? styles.navAnimate:""}`} 
          style={{animationDelay: `${index / 7 + 0.5}s`}} to={page.link}>
              {page.name}
          </Link>
        ))}
      </div>
      <div className={`${styles.burger} ${navbarState? styles.toggle:""}`} onClick={toggleNavbar}>
        <div className={styles.line1}></div>
        <div className={styles.line2}></div>
        <div className={styles.line3}></div>
      </div>
    </nav>
  )
}

export default Navbar

您再也不會將 navbarState 設置為 false ,而且將添加事件偵聽器效果更好,因此請嘗試以下操作:

//only set the event listener on mount
useEffect(() => {
  let windowResized = () => {
    let windowWidth = window.innerWidth;

    if (windowWidth > 576) {
      // if (navbarState) { this was a stale closure
      setNavbarState(false);
      console.log('Toggle navbar - Width > 576');
    } else {//not sure if you need this else
      console.log('Window is bigger than mobile');
      //set it to true again when it goes over 576 (not sure if you need this)
      setNavbarState(true);
    }
  };
  window.addEventListener('resize', windowResized);
  //probably never happens to layout but if unmounted
  //  remove the event listener
  return () =>
    window.removeEventListener('resize', windowResized);
}, []);

如果您希望 navbarState 在調用 setNavbarState 后立即更改,則切換也可能是錯誤的,而是試試這個

setNavbarState((navbarState) => {
  const newState = !navbarState;
  if (newState) {
    props.updateClassNames(styles.contentLeftAnimate);
  } else {
    props.updateClassNames(styles.contentRightAnimate);
  }
  return newState;
});

暫無
暫無

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

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