애플리케이션의 비동기 처리는 빈번하게 발생하므로 비동기 요청의 응답을 기다리는 동안 사용자에게 로딩을 표시해줘야한다. 재사용이 가능한 컴포넌트로 로딩 컴포넌트를 만들어보자.
✏️ 접근성 고려 접근성을 고려하였을 때, 스크린 리더가 로딩중이 시작할 때와 로딩이 종료되었을 때를 읽을 수 있도록 하기 위해서는 public 폴더에 index.html 파일에 다음과 같이 기재가 되어있어야한다.
1 2 3 4 5 6 // public/index.html <body > <div id ="loading-start" aria-live ="assertive" > </div > <div id ="loading-end" aria-live ="assertive" > </div > </body >
aria-live="assertive"
속성을 주어 다른 것보다 우선적으로 스크린 리더가 읽도록 설정해준다.
예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 const loadingElements = { start : document .getElementById ("loading-start" ), end : document .getElementById ("loading-end" ), }; export class Spinner extends React.Component { static defaultProps = { type : "connect" , message : "로딩 중..." , showMessage : true , timeToDisappear : { start : 1500 , end : 2500 , }, }; render ( ) { const { type, message, showMessage } = this .props ; const spinnerImagePath = getAsset (`spinner/spinner-${type} .gif` ); return ( <figure className ={styles.container} > <img className ={styles.image} src ={spinnerImagePath} alt ="" /> {showMessage ? ( <figcaption > {message}</figcaption > ) : ( <A11yHidden as ="figcaption" > {message}</A11yHidden > )} </figure > ); } componentDidMount ( ) { const { start } = loadingElements; start.setAttribute ("role" , "alert" ); start.insertAdjacentHTML ( "beforeend" , `<span class="a11yHidden">${this .props.message} </span>` ); } componentWillUnmount ( ) { const { start, end } = loadingElements; const { timeToDisappear } = this .props ; setTimeout (() => { start.removeAttribute ("role" ); start.innerHTML = "" ; end.insertAdjacentHTML ( "afterbegin" , `<span class="a11yHidden">로딩이 종료되었습니다.</span>` ); }, timeToDisappear.start ); setTimeout (() => { end.innerHTML = "" ; }, timeToDisappear.end ); } }
loading 요소를 반복적으로 사용할 것이기 때문에 최상단에 객체의 프로퍼티로 등록시켜주었다.
Spinner 컴포넌트의 기본 props값을 설정해주었다.
이는 컴포넌트를 만든 사람만 알 수 있기때문에 문서화를 하거나 TypeScript를 사용하여 개발자 경험(DX)를 높일 수 있다.
로딩중이라는 메시지를 보여주는 경우와 그렇지 않는 경우를 나누었다. 보여주지 않는 경우에는 접근성 컴포넌트로 생성하여 스크린 리더에는 읽히도록 설정해주었다.
컴포넌트가 mounted 될 때, role="alert"
속성을 주어 스크린 리더가 읽고 있는 것을 중지하고 로딩중을 읽도록 설정하였다.
StrictMode 에서는 mounted - unmounted - mounted 되는 특징 때문에 2번 작동할 수 있으므로 성능을 고려하여 clean Up을 해줘야한다.