refactor: make use-intersection-observer hook
This commit is contained in:
parent
cdc9de27f3
commit
6e3a498d46
@ -1,40 +1,16 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Users } from 'lucide-react';
|
import { Users } from 'lucide-react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||||
|
|
||||||
|
import { useIntersectionObserver } from '../hooks/use-intersection-observer';
|
||||||
import AnimatedCounter from './animated-counter';
|
import AnimatedCounter from './animated-counter';
|
||||||
|
|
||||||
export default function AboutCounter() {
|
export default function AboutCounter() {
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
|
||||||
const sectionRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const { t } = useTextController();
|
const { t } = useTextController();
|
||||||
|
|
||||||
useEffect(() => {
|
const { sectionRef, isVisible } = useIntersectionObserver<HTMLDivElement>();
|
||||||
const observer = new IntersectionObserver(
|
|
||||||
(entries) => {
|
|
||||||
const [entry] = entries;
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
setIsVisible(true);
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
threshold: 0.1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sectionRef.current) {
|
|
||||||
observer.observe(sectionRef.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
observer.disconnect();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
31
src/shared/hooks/use-intersection-observer.ts
Normal file
31
src/shared/hooks/use-intersection-observer.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
export const useIntersectionObserver = <T extends HTMLElement>() => {
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
const sectionRef = useRef<T>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
const [entry] = entries;
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setIsVisible(true);
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
threshold: 0.1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (sectionRef.current) {
|
||||||
|
observer.observe(sectionRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { sectionRef, isVisible };
|
||||||
|
};
|
||||||
@ -1,40 +1,15 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import { Container } from '@/shared/components/container';
|
import { Container } from '@/shared/components/container';
|
||||||
|
import { useIntersectionObserver } from '@/shared/hooks/use-intersection-observer';
|
||||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||||
|
|
||||||
import AnimatedCounter from '../shared/components/animated-counter';
|
import AnimatedCounter from '../shared/components/animated-counter';
|
||||||
|
|
||||||
export function StatsSection() {
|
export function StatsSection() {
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
|
||||||
const sectionRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const { t } = useTextController();
|
const { t } = useTextController();
|
||||||
|
|
||||||
useEffect(() => {
|
const { sectionRef, isVisible } = useIntersectionObserver<HTMLDivElement>();
|
||||||
const observer = new IntersectionObserver(
|
|
||||||
(entries) => {
|
|
||||||
const [entry] = entries;
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
setIsVisible(true);
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
threshold: 0.1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sectionRef.current) {
|
|
||||||
observer.observe(sectionRef.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
observer.disconnect();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section ref={sectionRef} className='bg-red-600 text-white'>
|
<section ref={sectionRef} className='bg-red-600 text-white'>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user