import { useEffect, useRef, useState } from 'react';
import { tw, keyframes, animation } from 'twind/css';
const FadeInUp = keyframes({
'0%': {
opacity: `0.1`,
transform: `translateY(50px)`,
},
'100%': {
opacity: `1`,
transform: `translateY(0px)`,
},
});
const fadeInUpAnimation = animation(`1.6s ease-out`, FadeInUp);
interface Children {
children: any;
}
const Title = ({ children }: Children) => (
<div
className={tw(`text-[#333D4B]
text-2xl
sm:text-4xl`)}
>
<h2>{children}</h2>
</div>
);
const Desc = ({ children }: Children) => (
<div className={tw(`text-[#4E5968] my-4`)}>
<p>{children[0]}</p>
<p>{children[1]}</p>
</div>
);
const Imgs = ({ children }: Children) => <img className={tw(``)} src={`/images/${children}.png`} alt={children} />;
const TDIcomponent = ({ props }: { props: { title?: string; desc?: string[]; _img?: string } }) => {
const { title, desc, _img } = props;
const [onScreen, setOnScreen] = useState(false);
const ioRef = useRef<any>();
const obCallBack = () => {
setOnScreen(true);
};
useEffect(() => {
const io = new IntersectionObserver(
([entries]: any) => {
if (entries.isIntersecting) {
obCallBack();
io.unobserve(entries.target);
}
},
{ threshold: 0.6 },
);
// eslint-disable-next-line no-unused-expressions
ioRef.current && io.observe(ioRef.current);
}, [ioRef]);
return (
<div
id={title}
ref={ioRef}
className={tw`
flex flex-col animate-pluse ${onScreen && fadeInUpAnimation}
sm:flex-row items-center
`}
>
<div>
<Imgs>{_img}</Imgs>
</div>
<div
className={tw(`
w-5/6 text-xl
`)}
>
<Title>{title}</Title>
<Desc>{desc}</Desc>
</div>
</div>
);
};
export default TDIcomponent;
react의 lifecycle을 고려해 eventlistner를 붙여야 하며,
tsc는 null check를 해 ref가 null인 상태에서
dom이 전부 그려지고 나서 붙는 과정을 기다려주지 않고 에러를 뱉어낸다
따라서 그냥 any로 타입을 고정시키고 observer를 붙였다.
이렇게 해도 딱히 문제는 없이 작동한다.