analogcoding

react 에서 loading 표시하기 (progressbar , spinner) 본문

Be well coding/Learn more

react 에서 loading 표시하기 (progressbar , spinner)

be well 2020. 1. 16. 16:01

파일을 업로드 하거나 다운로드 하는 상황에서 유저에게 해당 load status 를 보여주기 위한 기능을 구현하게 되었습니다.

 

텍스트가 아닌 데이터 크기가 큰 파일을 유저가 업로드 , 다운 받을 수 있는 상황일 때로 가정합니다.

 

요청에 대한 대기 시간을 indicator 로 표시해주는데 스피너와 로딩바 두 가지를 사용해서 구현해보겠습니다.

 

axios 요청과 Material UI 컴포넌트를 사용하겠습니다.

 

https://material-ui.com/api/circular-progress/

 

CircularProgress API - Material-UI

The API documentation of the CircularProgress React component. Learn more about the props and the CSS customization points.

material-ui.com

먼저 스피너를 구현해보겠습니다. 데이터를 받아오는 동안 보여줄 스피너입니다.  

 async fetchSomeData(url: string, fileType: string, fileName: string) {
    let response
    await this.setState({
      loadingIndicator: true,
    })
    response = await Axios.get(url, { responseType: "blob" })
    
    await this.setState({
      loadingIndicator: false,
    })
    
    ...
   

 

loadingIndicator 라는 state 를 false 로 선언하고 setState 를 이용해서 요청이 일어나는 함수가 실행되면 state 를 true 로 바꿔줍니다.

 {this.state.loadingIndicator === true ? <CircularProgress className="spinner" /> : null}

그리고 삼항연산자를 사용하여 spinner 컴포넌트를 렌더해줍니다. 이제 요청함수가 실행되고 요청이 끝날 때까지 화면에서 스피너를

확인할 수 있습니다.


다음은 업로드 상황에서 업로드 되는 로딩 상황을 보여줄 로딩 바를 구현해보겠습니다.

let response = await axios.get(url, {
            onDownloadProgress: (progressEvent) => {
                let percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
//	axios 에 onDownloadProgress & onUploadProgress 를 사용하면
//	해당 데이터의 total 과 load 를 사용할 수 있습니다. 이를 활용해서 progressbar 의 value 로 사용합니다.
                console.log(progressEvent.lengthComputable);
                console.log(percentCompleted);
				this.setState({
					loadPercent : percentCompleted
				})
            }

...

total 과 load 를 % 단위로 만들고 나머지 부분은 위와 동일하게 구현하고 LineProgress 의 value 에 해당 값을 넣어줍니다.

      <LinearProgress variant="determinate" value={this.state.loadPercent} />

꼭 서버에서 데이터를 불러올 때 onDownloadProgress 에는 파일이 만들어지는 시간은 포함되지 않으니 클라이언트에서 임의에

이펙트를 주는 방법도 있습니다.

 

 

Tip!

responseType 이 blob 인 경우 크기가 큰 데이터를 가져오는 상황에서 사용되지만 error 가 발생할 경우 error 메세지 역시

blob 타입으로 넘어오게 됩니다. 해당 부분을 분기해주는 것이 좋다고 생각합니다.

 

 

Comments