안경잡이개발자

728x90
반응형

  이번 시간에는 React의 LifeCycle의 개념에 대해서 이해한 뒤에 API 호출에 대해서 알아보도록 하겠습니다. React는 말 그대로 프론트 엔드(Front-End) 라이브러리입니다. 따라서 서버 개발자와 API를 이용해서 소통할 수 있어야 합니다. 하지만 React를 처음 공부하시는 분은 정확히 언제 API를 호출해서 데이터를 가져와 화면에 보여주어야 할 지 감이 안 잡힐 수 있어요. 이번 시간에는 그러한 내용에 대해서 다룰 거예요.


초기 구성 ※


  React 컴포넌트 객체가 DOM에 실제로 삽입되기 전까지의 과정은 다음과 같습니다. 이러한 과정을 마운팅(Mounting)이라고 부릅니다.


  1) contructor()

  2) componentWillMount()

  3) render()

  4) componentDidMount()


  기본적으로 컴포넌트가 모두 구성된 직후인 componentDidMount() 함수에서 API 호출을 수행하면 효과적이라는 것만 기억하시면 됩니다. SNS에 처음 로그인 했을 때 최근 타임라인 데이터를 API로부터 호출해서 화면에 보여주는 것이 그 예시입니다.


※ 데이터 변경 ※


  기본적으로 화면에 특정한 객체를 렌더링하기 위해서는 props 혹은 state를 사용해야 합니다. props와 state는 이러한 과정이 서로 다르지만 대략적으로 다음과 같은 순서로 수행된다는 것을 기억하시면 됩니다.


  1) shouldComponentUpdate()

  2) componentWillUpdate()

  3) render()

  4) componentDidUpdate()


  기본적으로 컴포넌트의 데이터와 화면(View)에 출력된 내용이 다를 때 shouldComponentUpdate() 함수가 동작합니다. 이 함수는 기본적으로 true 값을 반환합니다. 또한 화면에 출력되는 화면 구성을 변경하고자 할 때는 componentDidUpdate()를 많이 사용합니다. 실제로 데이터 변경과 관련한 함수들을 우리가 처리하게 되는 일은 많지 않습니다. 


※ 컴포넌트 해제 ※


  컴포넌트가 마운팅 해제 될 때 수행되는 함수는 componentWillUnmount() 함수입니다. 우리는 이 함수를 이용해서 컴포넌트의 동작을 위해 사용되었던 메소드들의 리소스를 제거해주게 됩니다. 애플리케이션의 성능 향상을 위해서 사용되는 경우가 많은 함수입니다.


※ API 호출 예제 ※


  이제 실제로 위와 같은 라이프 사이클의 개념을 활용하여 API를 호출하는 예제를 다루어 보도록 하겠습니다. API 호출을 연습하고자 할 때는 가짜(Fake) 온라인 REST API 사이트를 이용하시면 됩니다. 


  ▶ JSON Placeholder 사이트: https://jsonplaceholder.typicode.com/

  


  사이트에 접속해서 [Try it]을 클릭해 보시면 그 결과 응답(Response) JSON 데이터를 확인할 수 있습니다.



  이제 우리는 결과 JSON 데이터에서 title 정보만 받아서 화면에 출력해보도록 하겠습니다.


※ JavaScript 소스코드 ※


class ApiExample extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      data: ''

    }

  }

  

  callApi = () => {

    fetch("https://jsonplaceholder.typicode.com/todos/1")

      .then(res => res.json())

      .then(json => {

        this.setState({

          data: json.title

        })

      })

  }

  

  componentDidMount() {

    this.callApi();

  }

  

  render() {

    return (

      <h3>{this.state.data ? this.state.data : '데이터 불러오는 중'}</h3>

    )

  }

  

}


ReactDOM.render(

  <ApiExample />, 

  document.getElementById('root')

);



728x90
반응형

'리액트(React)' 카테고리의 다른 글

React 이벤트 처리(Event Handling)  (2) 2019.01.04
React의 State  (0) 2018.12.25
React의 Component와 Props  (0) 2018.12.25
React에서 JSX란?  (0) 2018.12.25
코드펜(Codepen)을 이용한 React 개발환경 구축하기  (0) 2018.12.25

728x90
반응형

  흔히 소프트웨어에서는 프로그레스 바(Progress Bar)를 구현하여 API 로딩 메시지를 웹 사이트 상에 출력할 수 있습니다. 이번 시간에는 고객 목록을 불러오는 API를 요청했을 때 서버에서 응답을 늦게 하는 경우 로딩 메시지를 화면에 띄워주는 방법에 대해서 알아보도록 하겠습니다. 프로그레스 바 UI 또한 Material UI에 이미 구현이 되어 있습니다. 따라서 이를 단순히 사용해주면 됩니다.


  ▶ Material UI 프로그레스 바: https://material-ui.com/demos/progress/


  우리는 이 예제 중에서 [Determinate]을 선택해 구현해 보도록 하겠습니다.



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


  기본적으로 리액트 라이브러리가 처음 컴포넌트를 실행할 때는 다음의 순서를 따릅니다.


1) constructor()

2) componentWillMount()

3) render()

4) componentDidMount()


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


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


▶ App.js


  따라서 Circular Progress 라이브러리를 이용하여 프로그레스 바를 API 로딩 메시지 용도로 사용하도록 하겠습니다.


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';


const styles = theme => ({

root: {

width: "100%",

marginTop: theme.spacing.unit * 3,

overflowX: "auto"

},

table: {

minWidth: 1080

},

progress: {

margin: theme.spacing.unit * 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={classes.root}>

<Table className={classes.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 className={classes.progress} variant="determinate" value={this.state.completed} />

</TableCell>

</TableRow>

}

</TableBody>

</Table>

</Paper>

);

}

}


export default withStyles(styles)(App);


※ 실행 결과 ※


  API를 불러올 때의 화면입니다.



API가 불러와 졌을 때의 결과 화면입니다.



(+ 추가)


  효과적인 로딩 테스트를 위해서는 서버 API의 지연을 발생시키는 것이 좋습니다. 서버에서 응답(Response) 데이터를 보내주는 코드에 Timeout을 적용해 보세요. setTimeout(function() { 소스 코드 }, 지연 시간)의 문법으로 간단히 사용해 볼 수 있습니다.


728x90
반응형