Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

302
Views
Detect intersection between two components in React when one component has position: fixed

I am trying to implement an intersectionObserver to watch if a <Header/> isIntersecting, but specifically only with another <Component/>

MY ATTEMPT

import React, { useRef, useEffect } from "react";
import "./styles.css";
import Header from "./components/Header";
import SomeComponent from "./components/SomeComponent";

export default function App() {
  const header = useRef(null);
  const component = useRef(null);

  const handleOverlap = (entries, observer) => {
    entries.forEach((entry) => {
      console.log(entry.isIntersecting);
    });
  };

  useEffect(() => {
    const options = {
      root: component.current,
      rootMargin: "10px",
      threshold: 0.1
    };
    const observer = new IntersectionObserver(handleOverlap, options);
    observer.observe(header.current);
  }, []);

  return (
    <div className="App">
      <Header ref={header} />
      <div style={{ backgroundColor: "pink", height: "100vh" }}></div>
      <SomeComponent ref={component} />
    </div>
  );
}

My desired result is to receive a true value if at point the user is scrolling and the header component intersects with the target component. I have set the root in the options object to a ref of the target component. I'm definitely missing some key logic somewhere. Any help would be great.

SANDBOX

https://codesandbox.io/s/friendly-shirley-u603gt?file=/src/App.js

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Sharing my solution in case anyone should ever be in a similar situation.

My solution was to check for a scroll event as opposed to using the intersectionObserver I believe because my <Header/> is a fixed position element, it is taken out of the document flow and the observer can not detect a valid intersection between the two components.

Instead, my checkIfHeaderIsOverlapping function calls the .getBoundingClientRect() on the ref of each component, and applies some simple logic to detect an overlap/interection.

SOLUTION

import React, { useRef, useEffect, useState } from "react";
import "./styles.css";
import Header from "./components/Header";
import SomeComponent from "./components/SomeComponent";

export default function App() {
  const [isOverlapping, setIsOverlapping] = useState(false);
  console.log("is it true? =>", isOverlapping);

  const header = useRef(null);
  const component = useRef(null);

  function checkIfHeaderIsOverlapping() {
    if (header.current && component.current) {
      const a = header.current.getBoundingClientRect();
      const b = component.current.getBoundingClientRect();

      if (a.top <= b.top + b.height && a.top + a.height > b.top) {
        setIsOverlapping(true);
      } else {
        setIsOverlapping(false);
      }
    }
  }

  useEffect(() => {
    function watchScroll() {
      window.addEventListener("scroll", checkIfHeaderIsOverlapping);
    }
    watchScroll();

    return () => {
      window.removeEventListener("scroll", checkIfHeaderIsOverlapping);
    };
  });

  return (
    <div className="App">
      <Header ref={header} />
      <div style={{ backgroundColor: "pink", height: "100vh" }}></div>
      <SomeComponent ref={component} />
      <div style={{ backgroundColor: "green", height: "100vh" }}></div>
    </div>
  );
}

SANDBOX

https://codesandbox.io/s/friendly-shirley-u603gt?file=/src/App.js

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!