-
[React] Styled-Components를 이용한 애니메이션programing/Web 2021. 1. 30. 21:47
발단
이상형 월드컵을 구현하다가, 각 아이템을 선택했을 때 밋밋하게 사진이 바뀌는 것이 마음에 안들어서, 애니메이션 효과를 주려고 했다.
권장하는 방법
styled-components에서 특정 이벤트 시 애니메이션을 트리거 하는 방법은 안나와 있었다.
다만, 구글링을 해보니 다들 상태 기반 애니메이션을 사용하는 듯 했다.
const ItemContainer = styled.div<ItemContainerProps>` ... ${(props) => (props.isFadeOut ? fadeOutAnimation : null)}; `;
나의 구현
상태 기반으로 애니메이션을 트리거하기 위해, useState로 상태를 추가했다.
export function ShowWindow(props: ShowWindowProps) { const [isFadeOut, setIsFadeOut] = useState(false); const onClickItem = (itemIndex: number) => () => { setIsFadeOut(true); ... }; const onAnimationEnd = (e) => { ... }; return ( <SelectionArea> <ItemContainer isFadeOut={isFadeOut} onClick={onClickItem(leftItemIndex)} onAnimationEnd={onAnimationEnd} > ... </ItemContainer> <ItemContainer isFadeOut={isFadeOut} onClick={onClickItem(rightItemIndex)} onAnimationEnd={onAnimationEnd} > ... </ItemContainer> </SelectionArea> ); }
onClickItem
함수에서isFadeout
의 상태를true
로 변경하는데, 이 때 상태 변경에 따라 리렌더링이 되어, 한번 깜빡인 뒤 애니메이션이 실행되었다.원인
원인은 정확하진 않지만,
isFadeout
상태가 변경됨에 따라, 이 상태에 의존하는ImageContainer
가 리렌더링된 게 원인이 아닐까 싶다.해결
결국, 고전적인 방법인 클래스 네임 기반 애니메이션으로 방법을 바꾸었다. (겸사겸사 애니메이션 주체도 상위 컴포넌트로 바꿨다.)
const SelectionArea = styled.div` ... &.fade-out { animation: ${fadeOutKeyframes} 0.5s 1 ease alternate; } `;
export function ShowWindow(props: ShowWindowProps) { const [selectedIndex, setSelectedIndex] = useState(0); const selectionArea = useRef<HTMLInputElement>(null); const onClickItem = (itemIndex: number) => () => { setSelectedIndex(itemIndex); selectionArea.current?.classList.add('fade-out'); }; const onAnimationEnd = () => { selectionArea.current.classList.remove('fade-out'); ... }; return ( <SelectionArea ref={selectionArea} onAnimationEnd={onAnimationEnd}> <ItemContainer onClick={onClickItem(leftItemIndex)} > ... </ItemContainer> <ItemContainer onClick={onClickItem(rightItemIndex)} > ... </ItemContainer> </SelectionArea> ); }
사실 이게 올바른 방법인지는 잘 모르겠다. 리서치 하기가 넘 귀찮스..
'programing > Web' 카테고리의 다른 글
[web] Intersection Observer API와 활용 (0) 2021.05.16 [CSS] column-count를 이용하여 masonry layout 구현하기 (2) 2021.02.28 [Web] Web Storage에 대하여 (2) 2020.12.26 [Web] JSON Web Token (0) 2020.12.03 [WEB] CORS에 대한 정리 (0) 2020.07.22 댓글