리액트로 동적인 state 변경과 keyframe slideUp 애니메이션 구현하기

미연·2022년 4월 29일
2
post-thumbnail

현재 이 수업을 듣고 있는 학생 한 명의 정보를, 최대 3개까지 애니메이션으로 5000ms마다 하나씩 보여지도록 해야 한다!

아이디어 📚

방법 1. css top 위치를 하나씩 조정하기

// 아래 메서드를 돌린다면,
학생정보배열.map(((data, idx) => (<div className={idx+1}>{data}</div>))

// 아래처럼 열거가 될 것이다.
<div className='1'>고등학생 / 2학년</div>
<div className='2'>중학생 / 1학년</div>
<div className='3'>졸업생 / 3수 이상</div>

클래스 1, 2, 3의 위치를 css로 position: absolute;top으로 위치를 각각 알맞게 조정하여, 그 고정 위치에 보여지도록 하는 방법이다.

1이 자리에 와 있으면, 나머지 2,3은 display: none;
2이 자리에 와 있으면, 나머지 1,3은 display: none;
3이 자리에 와 있으면, 나머지 1,2는 display: none;

그런데 이 방법은, 3에서 1로 보여지도록 할 때의 top 위치가 모호해진다는 점과 배열의 원소 개수가 3개 미만일 수도 있다는 점이 고려되어 보류한 방법이다.


방법 2. state 값을 동적으로 변경하기

배열의 인덱스를 5000ms마다 카운트하여, 배열의 원소를 하나씩 보여지도록 하는 방법이다.

// countIndex를 5000ms마다 count 하는 로직을 useEffect와 setInterval 메서드로 처리하기

<div>{학생정보배열[countIndex]}</div>

이 방법은 css로 위치를 고려하지 않아도 되었고, 원소 개수가 몇 개든 상관없이 해결할 수 있다.
머릿속으로 대충 생각한 로직은 이 정도였고, 바로 구체화를 시켜주었다!


구현한 코드 🙌

 const [indexCount, setIndexCount] = useState(0)
 
// * 수강신청생 정보 banner slider */

  // 5000ms마다 year_info의 인덱스를 순서대로 카운트 처리
  useEffect(() => {
    // 변수를 선언해 주어야 clearInterval 메서드에 쓸 수 있음
    let timeCount

    // userArr의 정보를 받아온 후, 5000ms마다 카운트 처리
    if (userArr) {
      timeCount = setInterval(handleUserInfoValue, 5000)
    }

    // setInterval 메서드의 cleanup 처리
    return () => {
      clearInterval(timeCount)
    }
  }, [contentsData])

  // 카운트 값이 바뀔 때마다, 카운트가 year_info 배열 길이만큼 된다면 0으로 초기화 처리
  useEffect(() => {
    if (userArr) {
      if (indexCount == userArr.length) {
        setUserInfoCount(0)
      }
    }
  }, [indexCount])

// * 수강신청생 정보 banner slider */


 <div>{userArr[indexCount]}</div>

1. 첫번째 useEffect

  1. contentsData는 모든 정보를 API로 받은 state이다.
  2. 변수 timeCount을 선언하고, 이에 setInterval 메서드를 담아 5000ms마다 인덱스를 카운트해주는 콜백함수 handleUserInfoValue를 선언한다.
  3. 변수 timeCount를 선언하는 궁극적인 이유는, 이 변수가 클린업 처리에 쓰이는 clearInterval에 쓰이기 때문이다. 클린업 처리를 해주지 않으면 카운트 처리가 되지 않았다.

2. 두번째 useEffect

  1. indexCount 카운트 수가 변할 때마다 useEffect가 실행된다.
  2. indexCount 카운트 수가 학생정보배열 원소 개수와 동일하게 변경될 시, 바로 0으로 초기화된다.
  3. 0으로 초기화 되면 다시 카운트가 되어, 학생정보배열 원소를 다 돌게 되는 셈이다.

3. state 동적 변경

 <div>{userArr[indexCount]}</div>

이제 indexCount로 카운트가 5000ms마다 실행되니 동적으로 변경된다.

4. 마무리하면서 덤으로..!


API 데이터가 위처럼 전달되는 상황이었는데, / 양옆으로 띄어쓰기가 되지 않아 가독성이 좋지 않아 보였다.

  // 양옆으로 띄어쓰기를 추가하는 로직
  useEffect(() => {
    if (userArr.length !== 0) {
      for (let i in userArr) {
        userArr[i] = userArr[i].replace('/', ' / ')
      }
    }
  }, [userArr])

그래서 프론트 단에서 학생정보배열 원소를 반복문으로 돌면서, 띄어쓰기를 추가해주는 로직도 추가했다.

5. css keyframe

.div {
   background: linear-gradient(to top, #ccb3ff 30%, transparent 10%);
   animation: slideUp 5s infinite;
   -webkit-animation: slideUp 5s infinite;

   @keyframes slideUp {
            0% {
              transform: translateY(20px);
            }
            10% {
              transform: translateY(0);
            }
            95% {
              transform: translateY(0);
            }
            100% {
              transform: translateY(-55px);
            }
   }
}

slideUp 애니메이션으로 keyframe 조정시켰다.
이때 형광펜(?) 밑줄 효과도 같이 애니메이션 효과를 주는 것이 포인트였다!

profile
FE Developer

0개의 댓글