반응형

개요

 

전 포스팅에서 Node.js로 만든 서버 API를 React로 로딩하는데 걸리는 시간 동안 에러가 나거나

따로 설정을 해주어야 한다는 것을 볼 수 있었습니다.

 


설명

 

그래서 이번에는 Material UI에 있는 프로그래스바를 이용하여 로딩 화면을 구성해보도록 하겠습니다.

Material UI 사이트 : https://material-ui.com/demos/progress/

 


React의 라이프 사이클 (Life Cycle)

 

1. constructor()

2. componentWillMount()

3. render()

4. componentDidMount()

 

그리고 컴포넌트의 props 와 state가 변경될 때는 shouldComponentUpdate() 함수 등이 사용되어 실질적으로 다시 render() 함수를 불러와 뷰(View)를 갱신하게 됩니다. 또한 컴포넌트가 삭제될 때는 componentWillUnmount() 함수가 실행된다는 특징이 있습니다.

따라서 일반적으로 API를 불러와서 웹 사이트 화면에 특정한 뷰를 출력하고자 한다면 componentDidMount() 함수에서 API를 비동기적으로 호출하면 됩니다. 이후에 API에서 응답(response)이 돌아왔을 때 비로소 뷰가 갱신되므로 화면에 API 응답 결과를 출력할 수 있는 것입니다. 비동기적으로 호출한다는 점에서 API 서버에서 응답을 하지 않으면 사용자에게 로딩 화면만 출력이 됩니다.

 

비동기란 동시에 일어나지 않는 것을 의미합니다.


APP.js

 

import React, { Component } from 'react';
import Customer from './components/Customer'
import './App.css';
import Paper from '@material-ui/core/Paper';
import Table from '@material-ui/core/Table';
import TableHead from '@material-ui/core/TableHead';
import TableBody from '@material-ui/core/TableBody';
import TableRow from '@material-ui/core/TableRow';
import TableCell from '@material-ui/core/TableCell';
import CircularProgress from '@material-ui/core/CircularProgress';
import { withStyles } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/core/styles';

const styles = theme => ({
  root: {
  width: "100%",
  overflowX: "auto"
  },
  table: {
  minWidth: 1080
  },
  progress : {
    margin: 2
  }

});

class App extends Component {

  state = {
    customers:"",
    completed:0
  }

  componentDidMount() {
    this.timer = setInterval(this.progress,20);
    /*this.callApi()
    .then(res => this.setState({customers:res}))
    .catch(err => console.log(err));*/
  }

  componentWillUnmount() {
    clearInterval(this.timer);
  }

  callApi = async() => {
    const response = await fetch('/api/customers');
    const body = await response.json();
    return body;
  }

  progress = () => {
    const {completed} = this.state;
    this.setState({completed:completed>=100 ? 0:completed+1});
  }

  render() {
    const {classes} = this.props;
    return (
      <Paper className={styles("").root}>
        <Table className={styles("").table}>
          <TableHead>
            <TableRow>
              <TableCell>번호</TableCell>
              <TableCell>이미지</TableCell>
              <TableCell>이름</TableCell>
              <TableCell>생년월일</TableCell>
              <TableCell>성별</TableCell>
              <TableCell>직업</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {this.state.customers ? this.state.customers.map(c => {
            return <Customer key={c.id} id={c.id} image={c.image} name={c.name} birthday={c.birthday} gender={c.gender} job={c.job} />
            }) :
            <TableRow>
              <TableCell colSpan="6" align="center">
                <CircularProgress class Name = {classes.progress} variant="determinate" value={this.state.completed} />
              </TableCell>
            </TableRow>
            }
          </TableBody>
        </Table>
      </Paper>
    );
  }
}

export default withStyles(styles)(App);

 

API를 받아오는 속도가 상당히 빠르기 때문에 테스트를 위하여 Call API를 주석처리해 보았습니다.

 


결과

 

 

로딩이 쭉 되는 것을 볼 수 있습니다.

 


 

반응형

+ Recent posts