Skip to content

Commit c6d1f48

Browse files
committed
docs: update the recipes
1 parent e889d90 commit c6d1f48

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

docs/Recipes.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,44 @@ build it according to your needs.
2525
- Either hide the `<img />` with CSS, or skip rendering it until it's inside the
2626
viewport.
2727

28+
> 🔥 The example has been expanded to include support for the new native
29+
> `loading` attribute on images. If it's supported, we can skip the `useInView`
30+
> hook and render the `<img>`.
31+
>
32+
> See https://web.dev/native-lazy-loading for details about using the `loading`
33+
> attribute.
34+
>
35+
> [@charlietango/use-native-lazy-loading](https://www.npmjs.com/package/@charlietango/use-native-lazy-loading)
36+
> is a small hook that detects support for `loading` as a side effect.
37+
2838
```jsx
2939
import React from 'react'
40+
import useNativeLazyLoading from '@charlietango/use-native-lazy-loading'
3041
import { useInView } from 'react-intersection-observer'
3142

3243
const LazyImage = ({ width, height, src, ...rest }) => {
44+
const supportsNativeLoading = useNativeLazyLoading()
3345
const [ref, inView] = useInView({
3446
triggerOnce: true,
35-
threshold: 0,
47+
margin: '200px 0px',
3648
})
3749

3850
return (
3951
<div
40-
ref={ref}
52+
ref={supportsLazyLoading === false ? ref : undefined}
4153
style={{
4254
position: 'relative',
4355
paddingBottom: `${(height / width) * 100}%`,
4456
background: '#2a4b7a',
4557
}}
4658
>
47-
{inView ? (
59+
{inView || supportsNativeLoading ? (
4860
<img
4961
{...rest}
5062
src={src}
63+
width={width}
64+
height={height}
65+
loading="lazy"
5166
style={{ position: 'absolute', width: '100%', height: '100%' }}
5267
/>
5368
) : null}
@@ -64,7 +79,8 @@ Triggering animations once they enter the viewport is also a perfect use case
6479
for an IntersectionObserver.
6580

6681
- Set `triggerOnce`, to only trigger the animation the first time.
67-
- Use `threshold` to control when the animations triggers.
82+
- Use `margin` to offset the trigger points. It ensures that a fixed fixed
83+
amount is visible, regardless of the element size.
6884

6985
```jsx
7086
import React from 'react'
@@ -73,7 +89,7 @@ import { useSpring, animated } from 'react-spring'
7389

7490
const LazyAnimation = () => {
7591
const [ref, inView] = useInView(ref, {
76-
threshold: 0.5,
92+
margin: '-100px 0',
7793
})
7894
const props = useSpring({ opacity: inView ? 1 : 0 })
7995

@@ -92,16 +108,17 @@ export default LazyAnimation
92108
You can use `IntersectionObserver` to track when a user views your element, and
93109
fire an event on your tracking service.
94110

95-
- Set `triggerOnce`, to only trigger an event the first time the element enters the viewport.
96-
- Set `threshold`, to control how much of the element should visible before
97-
firing the event.
111+
- Set `triggerOnce`, to only trigger an event the first time the element enters
112+
the viewport.
113+
- Use `margin` to offset the trigger points. It ensures that a fixed fixed
114+
amount is visible, regardless of the element size.
98115

99116
```jsx
100117
import React, { useEffect } from 'react'
101118
import { useInView } from 'react-intersection-observer'
102119

103120
const TrackImpression = () => {
104-
const [ref, inView] = useInView({triggerOnce: true, threshold: 0.2})
121+
const [ref, inView] = useInView({ triggerOnce: true, margin: '-100px 0' })
105122
useEffect(() => {
106123
if (inView) {
107124
// Fire a tracking event to your tracking service of choice.

stories/Hooks.story.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,13 @@ storiesOf('useInView hook', module)
119119
</HookComponent>
120120
</ScrollWrapper>
121121
))
122+
.add('Multiple thresholds', () => (
123+
<ScrollWrapper>
124+
<HookComponent
125+
options={{ threshold: [0, 0.2, 0.4, 0.6, 0.8, 1] }}
126+
style={{ height: '150vh' }}
127+
>
128+
Header is fully inside the viewport
129+
</HookComponent>
130+
</ScrollWrapper>
131+
))

0 commit comments

Comments
 (0)