2
votes

I need to change the background of a JSX element when the page goes down by 320 px, all with useEffect and useState. So far I managed to change the state, but does not add background class of another color.

I am using NODE 8.9.3, NPM 5.5.1 and REACT JS 16.9.0

import React, { useEffect, useState } from 'react'

import { useScrollYPosition } from 'react-use-scroll-position'

import { Container } from '../../styles/Container'
import { ContainerCustom, HeaderComp } from './styles'

import Logo from './Logo'
import Menu from './Menu'
import Icons from './Icons'

const ContainerBox = () => {
  return (
    <ContainerCustom fluid>
      <Container>
        <HeaderComp>
          <Logo />
          <Menu />
          <Icons />
        </HeaderComp>
      </Container>
    </ContainerCustom>
  )
}

const Header = () => {
  const [back, setBack] = useState(0)

  const handleBackState = () => {
    const scrollY = window.scrollY
    if (scrollY > 320) {
      setBack(1)
      console.log(`Estado: ${back}`)
    } else {
      setBack(0)
      console.log(`Estado após remover: ${back}`)
    }
  }

  useEffect(() => {
    window.addEventListener('scroll', handleBackState)
    return () => {
      window.removeEventListener('scroll', handleBackState)
    }
  }, [handleBackState])
  return <ContainerBox className={back === 1 ? 'removeGradients' : ''} />
}

On console has the output State: 0, and after 320, State after remove: 1

1
You provided scrollY as a dependency to useEffect but this is only defined inside the handler not in the scope you call useEffect. Does that code even work? The correct dependency would be handleBackState which should be wrapped in useCallback. You could even inline it and let useEffect have no dependency at all. - trixn
I changed the scrollY for handleBackState in useEffect dependency ... continued working state but does not update the class. - Guilherme Moreira
Are you aware that scrollY is not defined in that scope unless you omitted some code? You can't use it there because it it only defined inside of the handler. The correct dependency would be handleBackState if anything. But you can just inline the handler inside of your useEffect. - trixn
Is ContainerBox even accepting the className property and forwarding it to the DOM element? - trixn
thank you very much. I was able to change the classes .. the error was exactly what commented ... the ContainerBox was not a DOM element, so I could not change the class ... I applied all the logic in the Container element and finally it worked. Thanks. - Guilherme Moreira

1 Answers

1
votes

Not every component also has a representation in the DOM. You need to apply the className to a component that actually has a corresponding DOM element to have your styles take any effect:

// className will not affect the DOM as this component does not render a DOM element
const WrappingComponent = ({className}) => (
    <WrappedComponent className={className} />
);

// this className will be applied to the div in the DOM
const WrappedComponent = ({className}) => (
    <div className={className}>Content here</div>
);