KYin
KYin

Reputation: 569

react-intersection-observer only works with the last elements

I'm trying to build the Lazy Loading feature with react-intersection-observer, the goal is to only load the images in the boxes if they're in the viewport.

How to fix this problem so it will only render out the boxes that are in the viewport?


Demo gif:

enter image description here


My code:

App.js

export const AppContext = createContext();

function App() {
  const { ref, inView, entry } = useInView({
    rootMargin: "50px 0px",
    initialInView: true
    // triggerOnce: true,
  });

  return (
    <AppContext.Provider value={{ ref, inView, entry }}>
      <div className="App">
        <Posts />
      </div>
    </AppContext.Provider>
  );
}

export default App;

Post.js

import { useContext } from 'react'
import { AppContext } from '../App'

function Post({ post }) {
  const { ref, inView } = useContext(AppContext)
  return (
    <div className="post" ref={ref}>
      {inView ? 
        <img src={post.imgUrl} alt={post.title} className="post__img" loading="lazy" />
        : <div className="post__img" />
      }
      <h1 className="post__title">{post.title}</h1>
    </div>
  )
}

export default Post

Update:

I updated the Codesandbox link below to move useInView to Post.js and removed the Context API. It works now!

Edit Lazy Loading with react-intersection-observer

Upvotes: 1

Views: 3434

Answers (1)

Osama Malik
Osama Malik

Reputation: 355

Firstly you are using context, it maintains a single state but in your case you want to track all post items separately so,

Just bring the useInView hook inside each component of Post.js and remove it from App.js

Upvotes: 4

Related Questions