Skip to content

Commit 401964b

Browse files
committed
feat: implement the useOnInView hook
1 parent 66cda4f commit 401964b

File tree

5 files changed

+1013
-2
lines changed

5 files changed

+1013
-2
lines changed

README.md

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ to tell you when an element enters or leaves the viewport. Contains [Hooks](#use
1010

1111
## Features
1212

13-
- 🪝 **Hooks or Component API** - With `useInView` it's easier than ever to
14-
monitor elements
13+
- 🪝 **Hooks or Component API** - With `useInView` and `useOnInView` it's easier
14+
than ever to monitor elements
1515
- ⚡️ **Optimized performance** - Reuses Intersection Observer instances where
1616
possible
1717
- ⚙️ **Matches native API** - Intuitive to use
@@ -71,6 +71,70 @@ const Component = () => {
7171
};
7272
```
7373

74+
### `useOnInView` hook
75+
76+
```js
77+
const inViewRef = useOnInView(
78+
(enterEntry) => {
79+
// Do something with the element that came into view
80+
console.log('Element is in view', enterEntry?.target);
81+
82+
// Optionally return a cleanup function
83+
return (exitEntry) => {
84+
console.log('Element moved out of view or unmounted');
85+
};
86+
},
87+
options // Optional IntersectionObserver options
88+
);
89+
```
90+
91+
The `useOnInView` hook provides a more direct alternative to `useInView`. It
92+
takes a callback function and returns a ref that you can assign to the DOM
93+
element you want to monitor. When the element enters the viewport, your callback
94+
will be triggered.
95+
96+
Key differences from `useInView`:
97+
- **No re-renders** - This hook doesn't update any state, making it ideal for
98+
performance-critical scenarios
99+
- **Direct element access** - Your callback receives the actual
100+
IntersectionObserverEntry with the `target` element
101+
- **Optional cleanup** - Return a function from your callback to run when the
102+
element leaves the viewport
103+
- **Similar options** - Accepts all the same [options](#options) as `useInView`
104+
except `onChange`, `initialInView`, and `fallbackInView`
105+
106+
The `trigger` option allows to listen for the element entering the viewport or
107+
leaving the viewport. The default is `enter`.
108+
109+
```jsx
110+
import React from "react";
111+
import { useOnInView } from "react-intersection-observer";
112+
113+
const Component = () => {
114+
// Track when element appears without causing re-renders
115+
const trackingRef = useOnInView((entry) => {
116+
// Element is in view - perhaps log an impression
117+
console.log("Element appeared in view", entry.target);
118+
119+
// Return optional cleanup function
120+
return () => {
121+
console.log("Element left view");
122+
};
123+
}, {
124+
/* Optional options */
125+
threshold: 0.5,
126+
trigger: "enter",
127+
triggerOnce: true,
128+
});
129+
130+
return (
131+
<div ref={trackingRef}>
132+
<h2>This element is being tracked without re-renders</h2>
133+
</div>
134+
);
135+
};
136+
```
137+
74138
### Render props
75139
76140
To use the `<InView>` component, you pass it a function. It will be called
@@ -145,6 +209,13 @@ Provide these as the options argument in the `useInView` hook or as props on the
145209
| **initialInView** | `boolean` | `false` | Set the initial value of the `inView` boolean. This can be used if you expect the element to be in the viewport to start with, and you want to trigger something when it leaves. |
146210
| **fallbackInView** | `boolean` | `undefined` | If the `IntersectionObserver` API isn't available in the client, the default behavior is to throw an Error. You can set a specific fallback behavior, and the `inView` value will be set to this instead of failing. To set a global default, you can set it with the `defaultFallbackInView()` |
147211
212+
`useOnInView` accepts the same options as `useInView` except `onChange`,
213+
`initialInView`, and `fallbackInView`, and adds the following configuration:
214+
215+
| Name | Type | Default | Description |
216+
| ----------- | --------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
217+
| **trigger** | `"enter"` or `"leave"` | `"enter"` | Decide whether the callback runs when the element enters (`"enter"`) or leaves (`"leave"`) the viewport. |
218+
148219
### InView Props
149220
150221
The **`<InView />`** component also accepts the following props:

0 commit comments

Comments
 (0)