skip to Main Content

I am creating an application which in the scroll I have use intersection observer so in that program one error is comming can not property of null reading foreach and do some scroll in that application and observer the viewport ,so how to make it correct in that program ,code is given below

export default function App() {
  const card = document.querySelector(".card");
  const ob = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        entry.target.classList.toggle("show", entry.isIntersecting);
        if (entry.isIntersecting) ob.unobserve(entry.target);
      });
    },
    {
      threshold: 1
    }
  );
  card.forEach((card) => {
    ob.observe(card);
  });

  return (
    <div className="App">
      <div className="card-container">
        <div className="card show">This is a First card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a card</div>
        <div className="card">This is a Last card</div>
      </div>
    </div>
  );
}

2

Answers


  1. Try to wrap the intersectionObserver initialization inside useEffect.

    For Example –

    export default function App() {
    
      React.useEffect(() => {
        const card = document.querySelector(".card");
        const ob = new IntersectionObserver(
          (entries) => {
            entries.forEach((entry) => {
              entry.target.classList.toggle("show", entry.isIntersecting);
              if (entry.isIntersecting) ob.unobserve(entry.target);
            });
          },
          { 
            threshold: 1
          }
        );
        card.forEach((card) => {
          ob.observe(card);
        });
       }, []);
      
    
      return (
        <div className="App">
          <div className="card-container">
            <div className="card show">This is a First card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a card</div>
            <div className="card">This is a Last card</div>
          </div>
        </div>
      );
    }
    
    Login or Signup to reply.
  2. You shouldn’t use document outside of an effect in React, and in this particular case you are getting null on document.querySelector because those elements haven’t been mounted yet when you call it.

    You can easily solve your issue by moving everything into a useEffect hook, but it’s still weird to use document.querySelector in React since you are essentially bypassing it.

    Although in this case it’s debatable. Depending on the context, those cards might come from an API call (since they look like an array), or your could manually a constant array with the data they need outside of your component.
    The idea is to be able to use .map to iterate through them.

    The point is this isn’t always possible. Those cards might be separate static sections of a landing page with completely different shapes and components, and in that case you have two approaches:

    • One is two add a ref on the container, and iterate through its child nodes in the effect (instead of using document.querySelector you would use ref.current.children).
    • The other is to do like you are doing, using some sort of query selector.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search