2

I'm using a function to animate elements when getting into viewport but I would like to change it so it will do it only once...I/m not sure how/where to edit to accomplish this...any advice?

function useIsInViewport(ref) { const [isIntersecting, setIsIntersecting] = useState(false); const observer = useMemo( () => new IntersectionObserver(([entry]) => setIsIntersecting(entry.isIntersecting), ), [], ); useEffect(() => { observer.observe(ref.current); return () => { observer.disconnect(); }; }, [ref, observer]); return isIntersecting; } 

On page I use a const for setting:

const ref1 = useRef(null); const isInViewport1 = useIsInViewport(ref1); 

Then setting a class on the element:

${isInViewport1 && "fadeInDown"} 

1 Answer 1

1

You need to call observer.unobserve(entry.target) after the first iteration. Like below in in your specific case:

function useIsInViewport(ref) { const [isIntersecting, setIsIntersecting] = useState(false); const observer = useMemo( () => new IntersectionObserver(([entry]) => { setIsIntersecting(entry.isIntersecting); observer.unobserve(entry.target); // line I added }), [] ); useEffect(() => { observer.observe(ref.current); return () => { observer.disconnect(); }; }, [ref, observer]); return isIntersecting; } 
Sign up to request clarification or add additional context in comments.

6 Comments

I've chnaged it to setIsIntersecting(entry.isIntersecting), observer.unobserve(entry.target) but that gives the error: 'entry' is not defined
Why you changed it? Cause it didn't work?
Because React is giving an error when using semicolon instead of a comma
Do you have { as I did?
Glad I could help. Though I think my comment // line I added is the reason why you did what you did. I should have mentioned I changed () to {}.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.