简体   繁体   中英

React Hook "React.useEffect" is called conditionally

I have a hook inside my component, which detects when I am scrolling down or up. This is the code:

const [scrollDirection, setScrollDirection] = React.useState('')
    const [prevOffset, setPrevOffset] = React.useState(0)
    const {width} = useWindowSize()
    const useScrollDirection = () => {
        if (typeof window !== 'undefined') {
        const nav = document.querySelector('.nav');

        const toggleScrollDirection = () => {
           let scrollY = window.scrollY
           if (scrollY === 0) {
               setScrollDirection('')
           }
           if (scrollY > prevOffset) {
               nav?.classList.remove('activee')
           } else if (scrollY < prevOffset) {
            nav?.classList.add('activee')
           }
           setPrevOffset(scrollY)
        }
        React.useEffect(() => {
            window.addEventListener("scroll", toggleScrollDirection)
            return () => {
                window.removeEventListener("scroll", toggleScrollDirection)
            }
        })
        return scrollDirection
    }
    }
    React.useEffect(() =>
    {
        
        if(width<600) {
            setMobile(true)
        }
        else setMobile(false)
    }, [width])

    useScrollDirection()

Eventually when I try to build the site, I get an error " React Hook "React.useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks". I wonder why is this happening? any idea to fix this? Thanks.

The error is pretty self descriptive:

React Hook "React.useEffect" is called conditionally.
React Hooks must be called in the exact same order in every component render.
Did you accidentally call a React Hook after an early return?

Documentation: https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

useEffect cannot be called within a function that is declared within a component. useEffect and other hooks must always be called in the exact same order every time a function is executed.

For your useScrollDirection function, you are declaring a hook (which is fine) but then you are using useEffect within the hook. The declaration of useScrollDirection must be moved to be outside of the component in order to use useEffect inside of it.

const useScrollDirection = () => {
  // ...
  useEffect(() => {
    // ...
  }, []);
};

const Component = () => {
  useScrollDirection();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM