Mohammed Altamash
Mohammed Altamash

Reputation: 41

How to change state of a component when the component is scrolled in view?

Suppose I have a web structure as follows:

<Header />
<Component1 />
<Component2 />
<Component3 />
<Component4 />

Every component has a state as [component1Active, setComponent1Active] = useState(false)

Now, at the start Component1 is in view.

What I want is when component2 is scrolled in view, then I want to setComponent2Active = true and component1 as false.

I tried using useEffect, but it does not work as the states of all components are set as true during loading.

I am using functional components

Please help, any suggestions will be much appreciated.

Thanks in advance

Upvotes: 0

Views: 818

Answers (1)

Martin Nester
Martin Nester

Reputation: 143

There is a react library on NPM called 'react-in-viewport' https://github.com/roderickhsiao/react-in-viewport Here is an example.

import handleViewport from 'react-in-viewport';

const Block = ({ inViewport, forwardedRef } ) => {
  const color = inViewport ? '#217ac0' : '#ff9800';
  const text = inViewport ? 'In viewport' : 'Not in viewport';
  return (
    <div className="viewport-block" ref={forwardedRef}>
      <h3>{ text }</h3>
      <div style={{ width: '400px', height: '300px', background: color }} />
    </div>
  );
};

const ViewportBlock = handleViewport(Block, /** options: {}, config: {} **/);

const App= () => (
  <div>
    <div style={{ height: '100vh' }}>
      <h2>Scroll down to make component in viewport</h2>
    </div>
    <ViewportBlock onEnterViewport={() => console.log('enter')} onLeaveViewport={() => console.log('leave')} />
  </div>
)

Using const newComponent = handleViewport(<YourComponent/>) you can create any component into one that has the {inViewport, forwardedRef} props, on the containing element of your component set the ref attribute equal to forwardRef then you can use the inViewport prop to determine if it is in view. You can also use the onEnterViewport and onLeaveViewport attributes of the component created by handleViewport() to know the visibility of the component.

You can add the library to your project through either of the cli commands

npm install --save react-in-viewport

yarn add react-in-viewport

You could also do this yourself by accessing the document DOM with a listener on the scroll event and checking scrollHeight of the page and comparing it to the scrollHeights of each component. Using the library makes the implementation much less of a headache.

Upvotes: 1

Related Questions