본문 바로가기
개발(라이브러리,프레임워크)/react.js & react native

React Transition Group 적용 중 이슈사항

by zieunee 2022. 7. 2.
반응형

TransitionGroup와 CSSTransition 적용 해보았음

<TransitionGroup className='transitions-group'>
{showingList.map((item: any, index: number) => (
          <CSSTransition key={setTransitionKey(index)} in timeout={500} classNames='item' appear>
            {/* animation 설정  _global.css */}
            <BubbleHistoryItem
              className={`${position(item)}`}
              key={`history_${uuidv4()}`}
              style={{ opacity: setOpacity(index) }}>
              <Bubble className='Bubble' value={item.word} tailPosition={position(item)} />
            </BubbleHistoryItem>
          </CSSTransition>
        ))}
</TransitionGroup>

.item-enter-active {
    opacity: 0 !important;
  }
  .item-enter-done {
    opacity: 1 ;
    transition: opacity 500ms ease-in;
  }
  .item-exit {
    opacity: 1 !important;
  }
  // .item-exit-active {
  //   opacity: 0 !important;
  //   transition: opacity 500ms ease-in;
  // }
  // .item-exit-done {
  //   opacity: 0 !important;
  //   transition: opacity 500ms ease-in;
  // }

위처럼 하면 문제 생김 ..

이유는?

말풍선이 100개 넘게 있어도 화면에 보여줄 값은 전체 리스트에서 n개만 잘라서 보여주고 싶을때 리스트에 추가할때 고유값을 붙이는 경우가 많지만 리스트를 잘라서 n개만 보여줄때에는 index가 아주아주 고유값이게 되면 n개 + n개 가 보여지는 현상이 나타난다. 고유한 키값으로 인해 다른 리스트로 인식함. 그게 CSSTransition에도 같은 이슈가 있어 li태그 위에 설정한 key를 고유하게 만들어 버리면 내가 자른 n개 +1 로 생기는 현상이 생김

그래서 li태그 말고 bubble 컴포넌트인 div태그 위로 위치를 바꾸고 마지막 말풍선에만 className을 다르게 주어서 그 말풍선만 css동작을 하게끔 설정해 주었다. 그리고 list에 key는 index로 지정하여 n개의 키를 정해두고 덮어쓰게 하는 방식으로 하면 자연스럽게 말풍선이 올라가는 듯한 느낌이 되는것같음 ..

<BubbleHistoryList className={className}>
      <TransitionGroup className='transitions-group'>
        {showingList.map((item: any, index: number) => (
          <BubbleHistoryItem
            className={`${position(item)}`}
            key={`history_${index}`}
            style={{ opacity: setOpacity(index) }}>
            <CSSTransition key={uuidv4()} in timeout={500} classNames={setTransitionClass(index)} appear={false}>
              <Bubble className='Bubble' value={item.word} tailPosition={position(item)} />
            </CSSTransition>
          </BubbleHistoryItem>
        ))}
      </TransitionGroup>
    </BubbleHistoryList>

그래서 저렇게 사용하려 했는데 오류남 .. 왜죠? 

Warning: Unknown event handler property `onExited`. It will be ignored.

react-dom.development.js:67 Warning: Received `true` for a non-boolean attribute `in`.

If you want to write it to the DOM, pass a string instead: in="true" or in={value.toString()}.

transition-group 아래 직계 child에 CssTransition이 없었기 때문에 생긴 문제 중간에 BubblehistoryItem이 있어서 생긴 문제이다. 

 

그래서 다시 Transition으로 돌아감.. BubbleHistoryItem 에 고유값을 주지말고 index를 줘야 n개로 잘랐을때 효과가 자연스럽게 나온다. 리스트는 그대로이고 text만 덮어씌우기 때문에 ..! 

<BubbleHistoryList className={className}>
      {showingList.map((item: any, index: number) => (
        <BubbleHistoryItem
          className={`${position(item)}`}
          key={`history_${index}`}
          style={{ opacity: setOpacity(index) }}>
          <Transition key={uuidv4()} in timeout={500} appear>
            {status => (
              <Bubble
                className={`Bubble ${setTransitionClass(index, status)}`}
                value={item.word}
                tailPosition={position(item)}
              />
            )}
          </Transition>
        </BubbleHistoryItem>
      ))}
    </BubbleHistoryList>
  

//global.scss
.item-last-entering {
    opacity: 0 !important;
  }
  .item-last-entered {
    opacity: 1 ;
    transition: opacity 500ms ease-in;
  }
  .item-last-exiting {
    opacity: 1 !important;
  }
  .item-last-exited {
    opacity: 0 !important;
    transition: opacity 500ms ease-in;
  }

완성! 했는데 uuid로 고유 값으로 만들어 버리면 다시 다 렌더링 되어서 성능상 안좋다고 한다. 

id 값으로 대체 하기

    <BubbleHistoryList className={className}>
      {showingList.map((item: WordList, index: number) => (
        <BubbleHistoryItem
          className={`${position(item)}`}
          key={`history_${item.id}`}
          style={{ opacity: setOpacity(index) }}>
          <Transition key={item.id} in timeout={500} appear>
            {status => (
              <Bubble
                className={`Bubble ${setTransitionClass(index, status)}`}
                value={item.word}
                tailPosition={position(item)}
              />
            )}
          </Transition>
        </BubbleHistoryItem>
      ))}
    </BubbleHistoryList>
반응형