infodev
infodev

Reputation: 5235

Transform class component to functionnal component in reactJS

I would like to make a parralax effect in react.

I have found a tutorial on medium that explains how.

My code is written in functionnal component, but in example it's class component.

Here's the example

class Header extends React.Component {
  constructor() {
    super()

    this.state = {
      offset: 0
    };
  }
return (
  <header 
    className='header-background'
    style={{ backgroundPositionY: this.state.offset}}
  >
    <section
      className='info-container'
      style={{ bottom: this.state.offset / 2 }}
    >
      <h1>Kevin Simpson</h1>
      <h3>Front End Developer</h3>
    </section>
  </header>
)
}

componentDidMount() {
  window.addEventListener('scroll', this.parallaxShift);
}
componentWillUnmount() {
  window.removeEventListener('scroll', this.parallaxShift);
}
parallaxShift = () => {
  this.setState({
    offset: window.pageYOffset
  });
};

I transformed it as to functional with my knowledges

const [offset, setOffset] = useState(0);
useEffect(() => {
    window.addEventListener('scroll', setOffset(window.pageYOffset));
});
return (
  ...
  <svg style={{ bottom: offset }} className="border-circle" width={107} height={107} viewBox="0 0 107 107" >
  ....

Actually no setOffset is fired when I scroll, the event listener is not triggering events.

Upvotes: 0

Views: 34

Answers (1)

DpK
DpK

Reputation: 100

I see three issues with your code

  1. You are not removing your listener. This would cause memory leaks i.e performance issues.
  2. The second parameter of addEventListener has to be a function definition rather than a function call.
  3. useEffect executes everytime the component updates. To have the same functionality as componentDidMount add an empty array as the second parameter of useEffect so that its called only once after component initialization/mounting.

    useEffect(() => { window.addEventListener('scroll', () => setOffset(window.pageYOffset)); return () => window.removeEventListener('scroll', () => setOffset(window.pageYOffset)); },[]);

Writing your useEffect like this should work

Upvotes: 1

Related Questions