Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

110
Visualizações
IntersectionObserverAPI Return to default state when none of the elements are visible

I'm using a React Hook to detect when an element is visible in the viewport. Until then, everything works fine but I need to 'reset' the state when everything is hidden (like reaching the footer or the header).

Here's my hook:

import { useState, useEffect, useRef } from 'react'

const useIntersect = (ref) => {
  const [isOnScreen, setIsOnScreen] = useState(false)
  const observerRef = useRef(null)

  useEffect(() => {
    observerRef.current = new IntersectionObserver(([entry]) => {
      setIsOnScreen(entry.isIntersecting)
    })
  }, [])

  useEffect(() => {
    observerRef.current.observe(ref.current)
    return () => observerRef.current.disconnect()
  }, [ref])

  return isOnScreen
}

export default useIntersect

And here's the state I'm updating:

  const elementRef = useRef(null)
  const[state, setState] = useState('nothing is visible')
  const onScreen = useIntersect(elementRef)

  useEffect(() => {
    return onScreen ? setState('an item is visible') : null
  })

  return (
    <Item ref={elementRef}>
      ...
    </Item>
  )

I need to be able to say setState('...') to something (let's say a string) when all the elements are off the viewport (when the condition onScreen is not met) but even when I reach the footer when nothing is visible, it keeps the last item in memory.

I've tried many things but I cannot figure a way out :(

Thanks for the help!

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Your hook implementation seems fine. you might want to recheck the height of the Item component. check this code sandbox working fine with your hook implementation : https://codesandbox.io/s/elegant-wood-ruks2?file=/src/App.js

about 4 years ago · Juan Pablo Isaza Relatório

0

I believe your useIntersect hook should add a dependency on the ref.current instead of ref for the second useEffect

so

useEffect(() => {
  observerRef.current.observe(ref.current)
  return () => observerRef.current.disconnect()
}, [ref.current]);

and then when using it in the component do

useEffect(() => {
  return onScreen ? setState('an item is visible') : setState('nothing is visible');
}, [onScreen])

you should add a dependency on the onScreen so it only updates when the onScreen has changed, and lastly you should call setState for the scenario when the onScreen is false to the value you want.

about 4 years ago · Juan Pablo Isaza Relatório

0

I think the issue is with how you are passing elementRef to the hook.

useIntersect useEffect will not execute when elementRef changes.

import { useState, useEffect, useRef } from "react";

const useIntersect = () => {
  const ref = useRef(null);
  const [isOnScreen, setIsOnScreen] = useState(false);

  useEffect(() => {
    if (!ref) {
      const observer = new IntersectionObserver(([entry]) =>
        setIsOnScreen(entry.isIntersecting)
      );
      observer.observe(ref.current);
      return () => observer.disconnect();
    }
  }, [ref]);

  return [isOnScreen, ref];
};

export default useIntersect;

// -----------------------------Component-------------------------------
const [state, setState] = useState("nothing is visible");
const [onScreen, elementRef] = useIntersect();

useEffect(() => {
  return onScreen ? setState("an item is visible") : null;
});

return <Item ref={elementRef}></Item>;
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda