Reputation: 41
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
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