[2022.07.27] 리액트로 타이핑 효과 만들기

REASON·2022년 7월 27일
4

복습

목록 보기
7/12
post-custom-banner

리액트에서 타이핑 효과 만들기!

먼저 타이핑 효과를 어떻게 만들어야 할지 고민해보았다.
빈 글자로 시작해서 글자가 1개씩 추가되어야 한다.

  1. 완성할 텍스트를 미리 변수에 저장해놓기
const completionWord = 'Yuto Village';
  1. useState로 빈값 변수 하나 만들기!
    n초마다 이전 텍스트 + 현재 텍스트를 합쳐줘야 한다.
const [blogTitle, setBlogTitle] = useState('');
  1. 완성할 텍스트 길이를 초과하면 안되므로 (undefined가 계속 출력되는 무시무시한 일이 일어난다ㅠㅠ) 글자 수를 세는 카운트 state 변수 만들기
const [count, setCount] = useState(0);
  1. n초마다 글자 1개씩 추가해서 보여주기
useEffect(() => {
    const typingInterval = setInterval(() => {
     
      // 코드
    
    });
}, 300);

완성하려는 글자는 Yuto Village 이므로
처음에는 빈 글자 -> Y -> Yu -> Yut -> Yuto … 순서로 텍스트의 길이 - 1 만큼의 인덱스까지 보여줘야 한다.

0.3초마다 한 글자씩 보여주기로 했다.
interval을 사용할 것이므로 useEffect 에 코드를 작성해야 한다.

 useEffect(() => {
    const typingInterval = setInterval(() => {
      setBlogTitle((prevTitleValue) => {
        let result = prevTitleValue ? prevTitleValue + completionWord[count] : completionWord[0];
        setCount(count + 1);

        if (count >= completionWord.length) {
          setCount(0);
          setBlogTitle('');
        }

        return result;
      });
    }, 300);

    return () => {
      clearInterval(typingInterval);
    };
  });
  • 우선 interval 함수가 컴포넌트가 리렌더링 될 때 마다 생성될 수 있으므로 clear 해줄 수 있게 typingInterval이라는 변수에 담아주었다.

  • 그리고 0.3초마다 이 코드(setInterval)가 실행되는데 이 함수의 내용은 blogTitle의 값을 이전 값과 현재 count 인덱스 값의 글자를 합쳐서 리턴해주는 코드이다.

  • 이전 값을 가지고 현재 값을 변경시키고 있어서 setBlogTitle에 콜백함수를 사용하여 prevTitleValue를 인자로 받아와서 사용했다.
    만약 prevTitleValue가 falsy한 값이 아니라면 이전 값 + 현재 count 인덱스에 해당하는 글자가 합쳐질 것이고
    preveTitleValue가 falsy한 값이면 completionWord의 0번째 글자인 Y가 result에 담겨 리턴된다.

  • 가장 처음 글자는 이전 값 자체가 존재하지 않으므로 삼항 연산자를 사용하여 첫번째 글자를 출력할 수 있도록 만들었다.
    다음 글자를 출력하기 위해 count state값을 1 증가시키도록 했다.

  • 계속 반복하다가 count state 값이 완성할 글자의 길이와 같거나 큰 경우에 더이상 출력할 글자가 없으므로 count 변수를 0으로 만들고 blogTitle도 공백 문자로 만들어주었다.

전체 코드

import { useState, useEffect } from 'react';

const TypingTitle = () => {
  const [blogTitle, setBlogTitle] = useState('');
  const [count, setCount] = useState(0);
  const completionWord = 'Yuto Village';

  useEffect(() => {
    const typingInterval = setInterval(() => {
      setBlogTitle((prevTitleValue) => {
        let result = prevTitleValue ? prevTitleValue + completionWord[count] : completionWord[0];
        setCount(count + 1);

        if (count >= completionWord.length) {
          setCount(0);
          setBlogTitle('');
        }

        return result;
      });
    }, 300);

    return () => {
      clearInterval(typingInterval);
    };
  });

  return <h1 className="main-title">{blogTitle}</h1>;
};

완성한 텍스트 타이핑 효과

커서는 CSS after와 애니메이션을 사용해서 만들었다.
글자가 다 완성됐을 때 뒤에서부터 하나씩 지우는 기능도 추가해보고 싶다! 😊

post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 3월 30일

감사합니다!

답글 달기