React Waypoint Component
React Waypoint is a component designed to trigger functions whenever a specific element scrolls into or out of view within its container, including the window. It is currently at version 10.3.0 and is actively maintained, with regular minor and major releases addressing compatibility and performance. This library is commonly used for implementing features such as lazy loading, infinite scrolling, scrollspies, and elements that dock to the viewport. Its key differentiator is its straightforward React component API for handling scroll intersection events, abstracting away the complexities of `IntersectionObserver` or manual scroll event handling. It offers granular control over triggers with `onEnter`, `onLeave`, and `onPositionChange` callbacks, and supports both vertical and horizontal scrolling with configurable offsets.
Common errors
-
TypeError: (0 , react_waypoint__WEBPACK_IMPORTED_MODULE_0__.default) is not a function
cause Attempting to import `Waypoint` as a default export when it has been a named export since v9.0.0.fixChange your import statement from `import Waypoint from 'react-waypoint';` to `import { Waypoint } from 'react-waypoint';` -
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
cause This error can occur if `react-waypoint` itself or its peer dependency `react` is not correctly imported or installed, or if the `Waypoint` component is not being used as a valid React component.fixVerify that `react-waypoint` and `react` are installed (`npm install react-waypoint react`) and that `Waypoint` is imported as a named export: `import { Waypoint } from 'react-waypoint';`. Check for duplicate `react` installations or incorrect bundler configurations. -
Failed prop type: Invalid prop `children` supplied to `Waypoint`. Expected a single React element.
cause The `Waypoint` component was rendered with multiple children or an invalid child type.fixEnsure that if you pass children to `Waypoint`, there is only a single React element. For example, wrap multiple elements in a `<div>` or `<React.Fragment>` if you need to track a group of elements.
Warnings
- breaking The `Waypoint.getWindow()` static method was removed.
- breaking The `Waypoint` component is no longer a default export; it is now a named export. This means the import statement must change.
- breaking React version 15.3.0 or higher is now required. This might break applications running older React versions.
- breaking Changes in the ES module entry point might affect bundlers or environments that were relying on specific `package.json` exports.
- gotcha Waypoint callbacks (`onEnter`, `onLeave`) only fire if the new position changed from the last known position. For infinite scroll, if the component re-renders but stays visible, it might not re-trigger.
Install
-
npm install react-waypoint -
yarn add react-waypoint -
pnpm add react-waypoint
Imports
- Waypoint
import Waypoint from 'react-waypoint';
import { Waypoint } from 'react-waypoint'; - Waypoint (type)
import type { Waypoint } from 'react-waypoint'; - POSITION_BELOW
import { POSITION_BELOW } from 'react-waypoint';
Quickstart
import React, { useState, useCallback } from 'react';
import { Waypoint } from 'react-waypoint';
const ScrollSpyExample = () => {
const [currentSection, setCurrentSection] = useState('section1');
const handleEnter = useCallback((sectionName) => {
setCurrentSection(sectionName);
console.log(`Entered ${sectionName}`);
}, []);
return (
<div style={{ height: '300px', overflowY: 'scroll', border: '1px solid gray' }}>
<p>Scroll down to see Waypoint in action!</p>
<div style={{ height: '400px', background: '#e0ffe0', padding: '20px' }}>
<h2>Section 1 (Current: {currentSection === 'section1' ? '✅' : '❌'})</h2>
<p>This is the content for section 1.</p>
</div>
<Waypoint
onEnter={() => handleEnter('section1')}
bottomOffset="-100px"
/>
<div style={{ height: '400px', background: '#ffe0ff', padding: '20px' }}>
<h2>Section 2 (Current: {currentSection === 'section2' ? '✅' : '❌'})</h2>
<p>More content for section 2.</p>
</div>
<Waypoint
onEnter={() => handleEnter('section2')}
bottomOffset="-100px"
/>
<div style={{ height: '400px', background: '#e0e0ff', padding: '20px' }}>
<h2>Section 3 (Current: {currentSection === 'section3' ? '✅' : '❌'})</h2>
<p>Final section content.</p>
</div>
<Waypoint
onEnter={() => handleEnter('section3')}
bottomOffset="-100px"
/>
</div>
);
};
export default ScrollSpyExample;