intersectionObserver API + tsx

YOUNGJOO-YOON·2021년 12월 24일
0

react with webpack 5

목록 보기
37/37
post-custom-banner
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를 붙였다.

이렇게 해도 딱히 문제는 없이 작동한다.

profile
이 블로그의 글은 제 생각을 정리한 글과 인터넷 어딘가에서 배운 것을 정리한 글입니다. 출처는 되도록 남기도록 하겠습니다. 수정 및 건의 오류 등이 있으면 언제든지 댓글 부탁드립니다.
post-custom-banner

0개의 댓글