React library for using Intersection Observer API in a React-friendly way. Contains hooks to determine if an element entered the viewport or not, and to tell what elements are currently in the viewport.
- π Detect if an element has entered or left the viewport.
- π Track which elements are currently in the viewport in real-time.
- π€ Execute customizable callbacks when an element enters or exits the viewport.
- βοΈ Customize the Intersection Observer API options.
- π Implement your custom conditions to determine element visibility.
- β‘οΈ Optimized performance with minimal re-renders, components render only when necessary.
- π οΈ Crafted with TypeScript, ensuring type safety.
- π€ Small size, does not need any extra dependencies.
Install react-intersection-observer-kit
npm install react-intersection-observer-kit
yarn add react-intersection-observer-kit
Getting started with React Intersection Observer Kit is a straightforward process. Follow the steps below to integrate the library into your React application and leverage the power of the Intersection Observer API. Whether you want to track elements entering the viewport, customize observer options, or implement callbacks for specific behaviors, this section guides you through the essential usage scenarios. Dive into the examples and start observing elements easily.
In your React application, you'll need to wrap the components that will use the Intersection Observer API hooks with the ObserverProvider. This provider is responsible for observing elements, updating the active elements' state, and executing the activity listeners.
import { ObserverProvider } from 'react-intersection-observer-kit';
import ExampleComponent from './ExampleComponent';
function App() {
return (
<ObserverProvider>
{/* Your components that use the Intersection Observer API hooks go here */}
<ExampleComponent />
</ObserverProvider>
);
}
export default App;
You can customize the Intersection Observer API by using the optional options prop to override the default options, and the optional activeCondition callback to override the default condition for changing the element's active state:
import { ObserverProvider } from 'react-intersection-observer-kit';
import ExampleComponent from './ExampleComponent';
function App() {
return (
<ObserverProvider
options={{
root: null,
rootMargin: '0px',
threshold: 0.5,
}}
activeCondition={(entry) => entry.isIntersecting}
>
{/* Your components that use the Intersection Observer API hooks go here */}
<ExampleComponent />
</ObserverProvider>
);
}
export default App;
Within the components that you want to observe, use the useRegister hook to register elements and the useActiveElements hook to get information about the currently active elements.
import { useRegister, useActiveElements } from 'react-intersection-observer-kit';
function ExampleComponent() {
// Register the element to be observed
const ref = useRegister('elementId');
// Get currently active elements IDs
const activeElements = useActiveElements();
return (
{/*Add the useRegister returned ref as ref for the element you want it to be observed*/}
<div ref={ref}>
{/*Component Content*/}
</div>);
}
export default ExampleComponent;
You can add extra behavior for each element when its active state changes by providing callbacks
import { useRegister, useActiveElements } from 'react-intersection-observer-kit';
function ExampleComponent() {
// Register the element to be observed
const ref = useRegister('elementId', {
onEntryActive: (entry) => {
// Your custom logic when the element's state changes to Active
},
onEntryInactive: (entry) => {
// Your custom logic when the element's state changes to Inactive
},
});
return <div ref={ref}>{/* Component Content */}</div>;
}
export default ExampleComponent;
If you need to observe a single element or a few elements which are independent of each other, you can use the useInViewport
hook, which does not need to be inside ObserverProvider
.
import { useInViewport } from 'react-intersection-observer-kit';
function LazyImage({ src, alt }) {
const [ref, inViewport] = useInViewport();
return <img ref={ref} src={inViewport ? src : ''} alt={alt} style={{ opacity: inViewport ? 1 : 0 }} />;
}
export default LazyImage;
// App.jsx
import { LazyImage } from './LazyImage';
function App() {
return (
<div>
<LazyImage src='https://example.com/image-name.jpg' alt='Lazy Image' />
</div>
);
}
You can customize useInViewport
also by overriding the observerOptions or inViewCondition
// ExampleComponent.jsx
import { useInViewport } from 'react-intersection-observer-kit';
function ExampleComponent() {
const [ref, inViewport] = useInViewport({
inViewCondition: (entry) => entry.isIntersecting,
observerOptions: { root: null, rootMargin: '0px', threshold: 0.5 },
});
return <div ref={ref}>{/* Component Content */}</div>;
}
Name | Type | Default | Description |
---|---|---|---|
children |
ReactNode[] | ReactNode (required) |
- | Components requiring access to the useRegister and useActiveElements Hooks. |
options |
IntersectionObserverInit (optional) |
{ root: null, rootMargin: '0px', threshold: 0.5 } |
Options for overriding the default Intersection Observer API settings. |
activeCondition |
(entry: IntersectionObserverEntry) => boolean (optional) |
entry => entry.isIntersecting |
Callback to determine when to update the active elements or not. |
- Note:
useRegister
is generic. In TypeScript, you can override the default type for the ref object by specifying the type when calling the hook (e.g.,useRegister<HTMLDivElement>()
).
param | Type | Default | Description |
---|---|---|---|
id |
string |
- | Optional ID to assign to the registered element. Must be specified if the element does not have an ID to work properly. |
onEntryActive |
(entry: IntersectionObserverEntry) => void (optional) |
- | Callback invoked when the element's activeCondition becomes true. |
onEntryInactive |
(entry: IntersectionObserverEntry) => void (optional) |
- | Callback invoked when the element's activeCondition becomes false. |
RefObject<HTMLElement>
: Reference to assign to the element that needs observation.
Array<string>
: Array containing the IDs of currently active elements.
Name | Type | Default | Description |
---|---|---|---|
observerOptions |
IntersectionObserverInit (optional) |
{ root: null, rootMargin: '0px', threshold: 0.5 } |
Options for overriding the default settings for Intersection Observer API. |
inViewCondition |
(entry: IntersectionObserverEntry) => boolean |
entry => entry.isIntersecting |
Callback to determine whether to update the inViewport state. |
[RefObject<T>, boolean]
: Tuple containing the element ref and a boolean indicating if the element is in the viewport. Use the returned ref to start observing an element.
Explore these practical examples to see how React Intersection Observer Kit can help you in different scenarios. You can find example implementations in the examples
folder of the package repository.
Animate elements when they enter the viewport using React Intersection Observer Kit.
Implement lazy loading for React components to optimize performance.
Lazy fetching of data when a component becomes visible in the viewport.
We welcome contributions from the community! If you'd like to contribute to the development of React Intersection Observer Kit, please follow these guidelines:
- Fork this repository to your GitHub account.
git clone https://github.com/WardKhaddour/react-intersection-observer-kit.git
Create a new branch for your changes.
git checkout -b feature/feature-name
git commit -m "Add your descriptive message here"
git push origin feature/your-feature-name
Open a pull request against the main
branch of the original repository.
If you encounter a bug, please open an issue with a detailed description.
Feel free to open an issue to suggest new features or improvements.
Share your experience using the library and provide feedback on what you find helpful or challenging.
This project is licensed under the MIT License - see the LICENSE file for details.