이 문서는 ToastMessage를 새로운 디자인에 맞춰 재개발 하면서, 기존에 있던 ToastMessage의 문제점 파악 및 보완 과정을 정리한 문서입니다.
기존에 사용하던 토스트 메시지 Store의 명은 CommonMessageStore였는데, 코드를 처음 보는 사람은 정확히 어떤 형태의 Message인지 바로 알아볼 수 없는 문제가 있었습니다.
그래서 이번에 ToastMessage를 재개발 함과 동시에 ToastMessageStore라고 명칭을 변경하였습니다.
showMessage
가 true
일 때, 즉 현재 출력중인 토스트 메시지가 있을 경우, this.hideToastMessage()
메서드가 호출되는데, 기존에 떠있던 토스트 메시지가 트랜지션 없이 바로 사라지면서 연출이 부자연스러워지는 문제가 생깁니다.showMessage
에 의존하게 되면서, 3번과 같은 문제가 생깁니다.ToastRefType
이라는 타입을 새로 만들었습니다.useImperativeHandle
Hook을 사용해서, 컴포넌트 외부에서 Toast 내부 State를 변경할 수 있도록 했습니다.ref.current?.closeToast()
호출을 통해, 컴포넌트 내부의 isVisible을 false로 변경)durationMillisec
속성을 통해 isVisible
상태를 해당 시간에 맞춰 변경해줍니다.isVisible
값을 판별하여 관련된 className을 추가해줌으로써 Toast가 위로 올라오는 트랜지션을 활성화시킵니다.Toast 컴포넌트의 interface입니다.
• 해당 메시지를 출력해주고 있는 Toast 컴포넌트를 연결해주기 위해 ref 속성을 정의합니다.
새로 만든 ToastMessageStore입니다.
deep: false
로 설정하면 MobX는 class 속성들의 참조 객체의 변화만 관찰하게 됩니다. 즉 messageList 내부의 요소들은 관찰하지 않고, 완전히 새로운 list 객체가 할당되는 것만 관찰합니다.ref
속성을 정의했습니다. 새로운 메시지를 출력하고자 showToastMessage
를 호출했을 때, 기존에 존재하던 모든 ToastMessage에 closeToast
명령을 내려 강제로 닫히게 한 후 새로운 Message를 messageList
에 추가합니다.messageId
는 렌더링 시 key를 부여하기 위함입니다.위처럼 작성한 토스트 출력용 컴포넌트를 앱 최상단인 _app.tsx에 추가해주었습니다.
messageList
의 항목들로 Toast 컴포넌트를 순차적으로 렌더링 해주는 동시에, 각 항목의 ref 속성에 해당 컴포넌트의 ref를 할당합니다.
ToastMessageStore
의 closeAllToastMessages
메서드가 정상적으로 동작합니다.makeAutoObservable
에 deep: false
를 전달하지 않을 경우, ref의 변화를 계속 감지하게 되어 무한 재귀에 걸리게 됩니다.Toast 컴포넌트가 완전히 사라졌을 때, ToastMessageStore
의 removeMessage
를 통해 데이터를 정리해줍니다.
개선된 ToastMessage는 위와 같이, 기존에 출력중이던 메시지가 있는 상황에서 새로운 메시지가 출력되는 경우, 이전 메시지가 자연스럽게 Fade-out 되면서 새 메시지가 Fade-in 되며, timeout 설정 충돌로 인해 부자연스럽게 갑자기 사라지는 문제도 해결되었습니다.
기존에 사용되던 ToastMessage 컴포넌트(현재는 ToastMessageDeprecated로 이름 변경)는 CommonMessageStore를 거쳐서 _app.tsx
에 있는 Global한 ToastMessage를 통해 출력되는 경우와, 별도의 컴포넌트 내에서 ToastMessage 컴포넌트를 독립적으로 사용하여 출력하는 경우가 공존했었습니다.
이 부분에 대한 일관성이 떨어진다고 판단하여, 모든 ToastMessage는 ToastMessageStore를 통해서만 출력하는 방식으로 통일했습니다.
알 수 없는 오류에 대한 Toast 메시지 출력을 자주 사용하는데, 이를 출력하기 위해서 매우 긴 코드를 매번 작성해야 했습니다.
대략 160군데에서 Occurence를 찾았는데, 긴 코드에 대한 피로감, 복사/붙여넣기로 인해 과도하게 생기는 중복 코드를 해소할 필요성을 느꼈습니다.
알 수 없는 오류 토스트 메시지의 특징:
위 특징을 토대로, ToastMessageStore에 오류 메시지만을 위한 별도의 method를 하나 추가했습니다.
showUnknownErrorMessage({ closable, bottomOffset }: Pick<IToastMessageProps, 'closable' | 'bottomOffset'> = {}) {
this.showToastMessage({
closable: closable ?? true,
bottomOffset,
icon: 'FAILED',
text: TOAST_MESSAGE['UNKNOWN_ERROR'],
});
}
코드의 양이 확연히 줄어듦으로써 코드 작성의 피로감도 많이 줄일 수 있을 것으로 기대됩니다.