[2] React.js 기초 다지기

Doozuu·2023년 3월 20일
0

React

목록 보기
14/23
post-custom-banner

📌 props

props는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달할 때 사용한다.

props를 전달받은 자식 컴포넌트에서는 데이터를 수정할 수 없다.
(데이터를 변경하기 위해서는 컴포넌트 내부에서만 사용하는 변수에 값을 넣어 사용해야 한다.)



📌 props 자료형 선언하기

자식 컴포넌트에서 props에 대한 자료형을 선언해 놓으면, 부모 컴포넌트에서 넘어오는 props 변수들의 자료형과 비교한다. 이때 자료형이 일치하지 않는다면 경고 메시지로 알려주기 때문에 잘못된 데이터를 확인할 수 있다.

리액트 기본 내장 패키지인 propTypes 를 import해 사용하면, 데이터 유효성 검증을 하고 콘솔에 경고 메시지를 출력한다.

import datatype from 'prop-types'

컴포넌트명.propTypes = {
	변수명 : datatype.number,
    변수명 : datatype.bool,
    변수명 : datatype.array,
    변수명 : datatype.object,
    변수명 : datatype.function,
}



📌 props 다양하게 사용하기

1. props Boolean으로 사용하기

props 값을 Boolean형으로 하위 컴포넌트에 전달할 경우 true나 false 중 하나를 할당한다.
변수를 선언한 후 값을 할당하지 않고 넘기면 true가 기본값으로 할당된다.


2. props 객체형으로 사용하기

props 값을 객체로 하위 컴포넌트에 전달할 경우, 자료형을 object로 선언한다.

import React from 'react';
import PropsObj  from './R020_PropsObj'

function App() {
	return(
     <PropsObj Object Json={{react : '리액트', twohundred: '200'}}/>
    )
}

객채 형태(객체 내부 변수들)의 자료형을 선언할 때는 shape라는 유형을 사용한다.

import React, {Component} from 'react';
import datatype from 'prop-types';

class R020_PropsObj extends Component{
	rener() {
     let {
     	Object Json 
     } = this.props
    }
    return (
    	{JSON.stringify(Object Json)}
    )
}

R020_PropsObj.proptypes = {
	Object Json : datatype.shape({
    	react: datatype.string,
        twohundred: datatype.number,
    })
}

3. props를 필수 값으로 사용하기

props의 자료형을 선언할 때 prop-types를 사용하는데, 자료형 설정 대신 isRequired를 조건으로 추가하면 변숫값이 없는 경우 경고 메시지가 발생할 수 있다.

컴포넌트명.propTypes = {
	prop명 : datatyep.isRequired,
}

4. props를 기본값으로 정의하기

props의 기본값은 부모 컴포넌트에서 값이 넘어 오지 않았을 때 사용한다.
defaultProps라는 문법을 사용한다.

컴포넌트명.defaultProps = {
	prop명 : "기본값" // 숫자, 문자열 등의 기본값 설정
}

5. props의 자식 Component에 node 전달하기

props를 하위 컴포넌트 태그 안쪽에 선언해 전달하는 것 이외에도 하위 컴포넌트 태그 사이에 작성된 node를 전달할 수 있다.

  • node : html 문서를 구성하는 포괄적인 개념. (ex. 문서 요소, 속성, 텍스트, 주석)

App.js

import PropsNode from './PropsNode';

function App(){
	return(
    	<div>
        	<PropsNode>
            	<span>node from App.js</span> // node
            </PropsNode>
        </div>
    )
}

export default App;

PropsNode.js

import React, {Component} from 'react';

class PropsNode extends Component{
	render(){
    	return(
        <div>
        	{this.props.children} // 상위 컴포넌트에서 전달한 노드 접근
        </div>
        )
    {
}



📌 state

props 와 state 의 차이점

props : 상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 사용
state : 하나의 컴포넌트 안에서 전역 변수처럼 사용



📌 state를 변경하는 방법

1. setState( ) 함수 사용하기

this.state.변수명 = value 처럼 state를 직접 변경하면 render() 함수를 호출하지 않으므로 화면에 보이는 state 값은 바뀌기 전 상태로 남게 된다.

따라서 setState() 함수로 state를 변경해야 render() 함수를 호출해 변경된 값을 화면에 보여줄 수 있다.

StateChange = () => {
	this.setState({변수명 : value});
}

2. state를 직접 변경한 후 forceUpdate( ) 함수 사용하기

this.state.변수명 = value 처럼 state를 직접 변경하고 forceUpdate() 함수로 화면을 새로고침하면 render() 함수를 호출해 변경된 값을 화면에 보여줄 수 있다.

StateChange = () => {
	this.state.변수명 = value;
    this.forceUpdate();
}



📌 class형 컴포넌트

class형 컴포넌트에는 ComponentPureComponent가 있다.

1. Component

: 비교 대상이 완전히 동일하지 않으면 변경이 발생했다고 본다.

setState() 함수로 실행한 값은 이전에 있던 state 변숫값과 동일하더라도 Component에서는 새로운 state 변수가 같은 이름으로 생성됐다고 인식한다.

2. PureComponent

: 비교 대상의 값을 비교해 동일하지 않으면 변경이 발생했다고 본다.

  • 불필요한 render() 함수 실행을 줄여 페이지 성능을 향상시킬 수 있다.
  • Component 대신 PureComponent를 import 해서 사용한다.
  • PureComponent에서는 기본적으로 변숫값만 비교하지만, 예외적으로 객체에 대해서는 참조 값을 비교한다.
    참조 값은 객체를 생성했을 때 저장되는 메모리 주소로, 완전히 동일한 객체라도 새로 선언하면 다른 참조 값은 갖는다.

+ shallow-equal 사용하기

shallow-equal 패키지는 PureComponent에서 state 값의 변경을 비교하는 것과 동일한 기능을 하는 함수를 제공한다. shallowEqualArrays() 함수를 사용하면 문자열과 배열은 값만 비교하고 객체는 참조 값을 비교한다.

npm install shallow-equal

Component 클래스에서도 shouldComponentUpdate()shallowEqualArrays()를 사용하면 PureComponent 클래스처럼 값만 비교해 render() 함수를 실행시킬 수 있다.



📌 함수형 컴포넌트 사용하기

함수형 컴포넌트 클래스형 컴포넌트와 달리, state가 없고 생명주기 함수를 사용할 수 없다.

import React from 'react';

function 함수명(props){
	let { contents } = props;
    return (
    	<h2>{content}</h2>;
    )
}

export default 함수명;



📌 hook 사용하기

함수형 컴포넌트에서 클래스형 컴포넌트와 같이 state와 생명주기 함수와 같은 기능을 사용하기 위해 hook을 이용한다.

대표적인 hook 함수에는 useState(), useEffect() 가 있다.

import React, { useState, useEffect } from 'react';

function 함수명(){
	const [state, setState] = useState('초기값');
    
    useEffect(() => {
    	console.log('useEffect');
    })
    
    return (
    	<div>
        	<h2>{state}</h2>
            <button onClick = {() => setState('state 바꾸기')}>버튼</button>
        </div>
    )
}

export default 함수명;



📌 Fragments 사용하기

컴포넌트 단위로 element를 return할 때 하나의 태그로 전체를 감싸지 않으면 에러가 발생한다. 이때 태그로 감싸면 불필요한 태그를 추가하지 않고 사용할 수 있다.

  • 태그를 약식으로 <>로 사용할 수 있다.

틀린 예시

import React, { useState } from 'react';

function 함수명(){
  	return(
         <p>내용</p>
         <span>내용</span>
  )
}
  
export default 함수명;

옳은 예시

import React, { useState } from 'react';

function 함수명(){
  	return(
  		<React.Fragment>
          <p>내용</p>
          <span>내용</span>
        </React.Fragment>
  )
}
  
export default 함수명;
import React, { useState } from 'react';

function 함수명(){
  	return(
  		<>
          <p>내용</p>
          <span>내용</span>
        <>
  )
}
  
export default 함수명;



📌 map()으로 element 반환하기

반복해서 출력해야 하는 element들을 배열에 넣어두고 map() 함수로 순서대로 나열해 컴포넌트를 return할 수 있다.

import React, { useState } from 'react';
  
function 함수명(){
  	const array = [
  		<li>list1</li>
  		, <li>list2</li>
  		. <li>list3</li>
  	]
  	return(
  		<ul>
          {array.map(el => el)};
        </ul>
  )
}
  
export default 함수명;



📌 reactstrap 사용하기

  • bootstrap은 프론트엔드 디자인을 쉽게 구현할 수 있도록 도와주는 html, css, js 프레임워크다.

  • bootstrap을 react에서 사용할 수 있도록 패키지로 만든 것이 reactstrap이다.

reactstrap 설치

reactstrap은 bootstrap css를 포함하고 있지 않기 때문에 bootstrap도 같이 설치해준다.

npm install --save reactstrap
npm install --save bootstrap

1. Alerts

알림 영역에 대한 기능을 제공한다.

참고

reactstrap에서 color 속성을 primary, secondary, success, danger, waring, light, dark 중에 선택하면 각각 다른 색을 적용할 수 있다.

App.js

import React from 'react';
import ReactstrapAlerts from '경로';
import 'bootstrap.css'  
  
function App(){
	return (
  		<ReactstrapAlerts/>
  )  
}

ReactstrapAlerts.js

import React, { useState } from 'react';
import { Alert, UnControlledAlert } from 'reactstrap';
  
function ReactstrapAlerts(){
  	return(
  		<div>
          <Alert color="light">
            Simple Alert [color : light]
          </Alert>
          <UnControlledAlert color="warning">
            UnControlled Alert [color : warning]
          </UnControlledAlert>  
        </div>
  )
}
  
export default ReactstrapAlerts;

2. Badge

부모 요소에 추가로 특정 문자열이나 숫자를 표시할 때 사용된다.

App.js

import React from 'react';
import ReactstrapBadges from '경로';
import 'bootstrap.css'  
  
function App(){
	return (
  		<ReactstrapBadges/>
  )  
}

ReactstrapBadges.js

import React, { useState } from 'react';
import { Badge, Button } from 'reactstrap';
  
function ReactstrapBadges(){
  	return(
  		<div>
          <h1>Product Name <Badge color="secondary"> hit</Badge></h1>
          <Button color="light">
           	<Badge color="dark"> 4</Badge>
          </Button>  
        </div>
  )
}
  
export default ReactstrapBadges;

3. Breadcrumbs

페이지 위치 경로를 지정한 웹 네비게이션에 사용된다.
보통 웹사이트 상단에 표시되는 메뉴 리스트에 사용하며 특정 메뉴를 선택하면 해당하는 페이지 위치로 이동시킨다.

App.js

import React from 'react';
import ReactstrapBreadcrumbs from '경로';
import 'bootstrap.css'  
  
function App(){
	return (
  		<ReactstrapBreadcrumbs/>
  )  
}

ReactstrapBreadcrumbs.js

import React, { useState } from 'react';
import { Breadcrumb, BreadcrumItem } from 'reactstrap';
  
function ReactstrapBreadcrumbs(){
  	return(
  		<div id="top">
          <Breadcrumb tag="nav" listTag="div">
            <BreadcrumItem tag="a" href="#top">Go top</BreadcrumItem>
             <BreadcrumItem tag="a" href="#bottom">Go bottom</BreadcrumItem>
          </Breadcrumb>
          <div id="bottom">
          </div>
        </div>
  )
}
  
export default ReactstrapBreadcrumbs;

4. Dropdown ⭐️

대표 메뉴를 검색하면 하위 메뉴 리스트가 표시되는 기능
App.js

import React from 'react';
import ReactstrapDropdown from '경로';
import 'bootstrap.css'  
  
function App(){
	return (
  		<ReactstrapDropdown/>
  )  
}

ReactstrapDropdown.js

import React, { useState } from 'react';
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';

function ReactstrapDropdown(){
  	return(
  		<ButtonDropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>  
  			<DropdownToggle caret> 버튼 Dropdown</DropdownToggle>  
 			<DropdownMenu>  
    			<DropdownItem header>헤더</DropdownItem> 
    			<DropdownItem disabled>비활성화 버튼</DropdownItem> 
    			<a href="http://example.com/">
      				<DropdownItem>example 웹 사이트로 이동</DropdownItem>  
    			</a> 
    			<DropdownItem onClick={e => alert("Alert 버튼")}> Alert 버튼 </DropdownItem> 
  		    </DropdownMenu> 
  		</ButtonDropdown>
  )
}
  
export default ReactstrapDropdown;

5. Button Group

비슷한 형태와 기능을 하는 버튼들을 그룹으로 관리할 수 있게 지원해준다.

6. Bottons

<Button> 태그에 color 속성에 약속된 문자열을 넣으면, 용도에 맞는 버튼 스타일을 지원해준다.

7. Card

이미지 제목, 부제목, 내용, 버튼 등을 한 세트로 묶는다.
Card 단위로 리스트를 만들어 반복해서 출력하면 정형화된 콘텐츠 목록을 만들 수 있다.

슬라이드를 자동으로 회전시키는 기능을 제공한다.

import React from 'react';
import { UncontrolledCarousel } from 'reactstrap';
  
const items = [
  { 
  	src : 'http://~~',
  	altText : '슬라이드1 이미지 대체 문구',
  	caption : '슬라이드1 설명',
  	header : '슬라이드1 제목',
  },
  {
  	src : 'http://~~',
  	altText : '슬라이드2 이미지 대체 문구',
  	caption : '슬라이드2 설명',
  	header : '슬라이드2 제목',
  },
  {
  	src : 'http://~~',
  	altText : '슬라이드3 이미지 대체 문구',
  	caption : '슬라이드3 설명',
  	header : '슬라이드3 제목',
  }
]  
  
funtion ReactstrapCarousel(){
  return(
  	<UncontrolledCarousel items={items} />
  )
}  

9. Collapse

특정 영역을 펼치고 숨기는 기능을 제공한다.

10. Fade

특정 영역을 서서히 나타내고 숨기는 기능을 제공한다.

11. Form

기존 <html form> 태그에 깔끔하고 정리된 스타일을 간편하게 사용해 사용할 수 있다.

11. Input Group

여러 개의 태그를 하나의 input 그룹으로 묶어 사용할 수 있도록 지원한다.

12. Jumbotron

Jumbotron은 대형 전광판을 의미한다. 넓은 영역에 눈에 띄게 정보를 표시해 사용자의 관심을 불러일으킬 수 있다.

13. List Group

정돈된 스타일의 목록을 표시할 때 사용한다.
Button과 링크에 별도의 태그를 추가하지 않고 속성 값으로 간편하게 사용할 수 있다.

14. Modal ⭐️

alert() 함수와 마찬가지로 사용자에게 원하는 시점에 알림 창을 띄워 필요한 내용을 보여준다. 웹 브라우저에서 팝업 창을 차단할 수 없고 배경 페이지와 어울리는 디자인을 적용할 수 있다.

14. Navbar

웹 사이트의 내부 페이지들로 쉽게 이동할 수 있도록 메뉴 리스트와 링크를 제공한다.

15. Pagination ⭐️

데이터 수가 많아 한 페이지에 모두 표시할 수 없을 때는 여러 페이지에 나눠 표시한다. 페이지 번호, 이전/다음 페이지 첫/마지막 페이지 버튼을 쉽게 구현할 수 있게 지원해준다.

16. Popovers

html 요소를 클릭했을 때 요소에 연결된 메시지 박스를 띄울 수 있는 기능을 제공한다.

17. Progress ⭐️

전체 작업에 대한 현재 진행 상태를 표현해준다.
진행 바 내부에 문자열을 넣을 수 있고, 색상을 적용할 수도 있다.

18. Spinner ⭐️

어떤 작업이 진행되고 있음을 표시하는, 움직이는 원 형태의 디자인을 제공한다.

19. Table ⭐️

<html table> 태그에 간편하게 스타일을 적용할 수 있도록 지원해준다.

20. Tab ⭐️

사용자 동작에 따라 특정 영역에 다른 내용을 표시할 때 사용한다.



📌 sweetalert2

sweetalert2는 다양한 디자인과 기능의 알림 창을 지원한다.
기본 자바스크립트 alert()와 같이 사용자에게 필요한 정보를 알림 창으로 표시한다.

설치

npm install sweetalert2

Basic

sweet2는 비동기적으로 동작하기 때문에 동기적으로 사용하기 위해 프로미스의 then 함수를 사용한다.

  • 동기 : 요청과 결과가 동시에 일어남
  • 비동기 : 요청과 결과의 작업 처리 단위를 맞추지 않음
  • 프로미스 : 비동기 함수를 동기적으로 사용할 수 있도록 하는 개념이다.
import React from 'react';
import Swal from 'sweetalert2';

function Sweetalert2Basic(){
	Swal.fire('1. SweetAlert').then(result => 
  	{ alert('2. alert()')} )
}

position

알림 창의 표시 위치를 결정한다.

confirm

실제 삭제 작업을 실행하기 전에 다시 한번 확인하는 알림 창을 표시한다.



📌 fetch get 호출하기

웹에서는 클라이언트와 서버가 http 프로토콜을 통해 요청과 응답을 주고받는다.
http에서 사용하는 방식은 여러 가지가 있지만, GETPOST를 가장 많이 사용한다.
GET은 데이터를 조회해 가져와 사용하는 것이다.

⭐️ GET 방식은 url? 뒤에 파라미터명=값 형태로 필요한 데이터를 전달한다. 주로 데이터 조회나 검색 등의 기능에 사용된다.

자바스크립트 내장 함수인 fetch를 사용하면 쉽게 비동기 통신을 구현할 수 있다. 비동기 통신이란, 쉽게 말해 먼저 시작한 작업의 완료 여부와 상관없이 다음 작업을 실행하는 것이다.

이때 fetch 함수의 비동기적 특징 때문에 아래 line 1에서 데이터를 가져오기 전에 line 2가 실행돼 에러가 발생할 수 있다.

이런 에러는 비동기 함수에 동기적인 기능을 추가해 해결할 수 있다. 이때 사용하는 것이 asyncawait 문법이다. 비동기 함수를 실행하는 함수에 async를 추가하고 동기적으로 처리돼야 하는 함수 구문 앞에 await를 추가한다.

import React, { useState, useCallback, useEffect }  from 'react';

function fetchGet(){
  	const [data, setData] = useState([]);
  
	const fetchHandler = useCallback(async () => {
      const response = await fetch('http://date.jsontest.com/'); // line 1
      const body = await response.json(); // line 2
  	  setData(body);
    }, [])
  
  	useEffect(FetchHandler,[FetchHandler]);
  
    return (
      <h1>fetch get</h1>
    )
}
  
export default fetchGet;

useCallback

콜백 함수의 최적화를 위해 useCallback을 사용한다.
useCallback은 해당 함수가 동일한 입력값을 받았을 때 이전에 계산한 결과를 재사용한다. 이를 통해, 같은 함수를 반복적으로 재생성하지 않고 기존의 함수를 재사용하므로서, 불필요한 렌더링을 줄일 수 있다.

useEffect

fetch 작업을 수행하는 코드를 useEffect 내에 작성하면, 컴포넌트가 렌더링되고 난 후에(fetch 작업이 끝나고 나서) 데이터를 가져와서 화면에 렌더링할 수 있다. 또한, useEffect를 사용하면 데이터를 가져오는 중에도 사용자 인터페이스가 멈추거나 끊김 없이 계속 작동할 수 있도록 보장할 수 있다.



📌 fetch post 호출하기

POST는 서버의 상태나 데이터를 변경하는 등의 수행 작업에 사용된다.

url 뒤에 파라미터를 표시하지 않고 사용할 수 있다는 장점이 있다.

fetch 방법은 get과 비슷하지만, 두 번째 파라미터에 post 호출에 대한 정보가 추가된다.

import React, { useState, useEffect } from 'react';

function fetchPost(){
  	const [data, setData] = useState([]);
  
	const fetchHandler = async () => {
      const response = await fetch('http://date.jsontest.com/', {
  		method : 'POST', // post 방식으로 통신을 하겠다는 의미
  		headers : {
  		'Content-Type' : 'application/json', 
  		// 어떤 형태의 데이터를 사용할지 지정한다. 
  		// json 형태의 데이터를 사용하기 위해 application/json을 할당한다.
  		},
  		body : JSON.stringify(data),
  	 });
   }
  
  	useEffect(FetchHandler,[FetchHandler]);
  
    return (
      <h1>fetch post</h1>
    )
}
  
export default fetchPost;



📌 axios get 사용하기

axios도 fetch와 마찬가지로 비동기 통신을 지원한다.
axios는 fetch와 달리, 별도로 설치한 후 import해 사용해야 한다.

npm install -save axios

⭐️ fetch와 axios의 차이점

fetch와 axios는 둘 다 JavaScript에서 HTTP 요청을 보내는 데 사용되는 라이브러리이다.
가장 큰 차이점 중 하나는 fetch가 내장된 브라우저 API이고, axios가 브라우저 및 Node.js에서 사용할 수 있는 JavaScript 라이브러리라는 것이다. 따라서 fetch는 브라우저에서 기본적으로 사용 가능하지만, Node.js에서는 추가 작업이 필요하다.
또한 axios는 fetch보다 강력한 기능을 제공한다. 예를 들어, axios는 HTTP 요청 및 응답을 자동으로 JSON으로 변환하고, 요청 취소 및 인터셉터 등과 같은 기능을 제공한다. 이러한 기능들은 fetch로 구현하기가 어렵거나 불가능하다.
하지만, fetch는 브라우저 API이므로 브라우저의 기능과 함께 사용될 때 일관성 있는 브라우저 경험을 제공할 수 있다.

import React from 'react';
import axios from 'axios'; // import 해오기
  
function AxiosGet(){
  	axios.get('http://date.jsontest.com/')
  	.then( response => alert(response.data.date))
  
	return(
 	 <h1>axios get</h1>
  	)	  
}

export default AxiosGet;



📌 axios post 사용하기

get 방식과 거의 동일하지만, post 함수의 파라미터로 json과 같은 형태의 데이터를 넣고 http body에 담아 url을 호출할 수 있다는 차이점이 있다.

json 데이터는 {key: value} 형태로 사용한다.

import React from 'react';
import axios from 'axios'; // import 해오기
  
function AxiosPost(){
  	axios.post('http://date.jsontest.com/',{
  	 a : "react", b : 200
  	})
  	.then( response => alert(response.data.date))
  
	return(
 	 <h1>axios post</h1>
  	)	  
}

export default AxiosPost;



📌 콜백 함수

자바스크립트는 비동기적으로 동작하기 때문에 먼저 실행된 작업이 끝나지 않았더라도 다음 작업이 시작될 수 있다.

대표적인 것이 setTimeout()함수이다.

setTimeout() 함수는 JavaScript에서 비동기적인 타이머를 설정할 때 사용하는 함수이다. 이 함수는 일정 시간이 지난 후에 지정된 콜백 함수를 호출한다.

1번 코드
2번 코드(setTimeout으로 2초 후 실행되도록 했을 때)
3번 코드

1번 -> 2번(2초 기다리고) -> 3번 순서대로(동기적으로) 실행되지 않고, 1번 -> 3번 -> 2번 순서대로(비동기적으로) 실행된다. 이를 동기적으로 실행시키고 싶을 때 콜백 함수를 사용해주면 된다.

function CallbackFunc(){
  	console.log("1번 코드");
  
    setTimeout(function(){
    console.log("2번 코드")
    }, 2000);
  
	console.log("3번 코드");
}
  
CallbackFunc();
// 실행 결과 : 1번 코드 -> 3번 코드 -> 2번 코드

콜백 함수를 이용하면 특정 코드에 순서를 정해 원하는 시점에 실행할 수 있다.
콜백 함수란 다른 함수의 인자로써 이용되는 함수로, 어떤 이벤트에 의해 호출되는 함수를 말한다.

위의 코드의 경우 빨간 부분이 콜백 함수에 해당한다.

setTimeout(function(){
console.log("2번 코드")
}
, 2000);


만약 1번 코드 -> 2번 코드 -> 3번 코드의 순서로 실행을 시키고 싶을 경우, 2번 코드의 콜백 함수 내부에서 다시 콜백 함수를 이용해 3번 코드를 호출하면 된다.

function CallbackFunc() {
  console.log("1번 코드");

  setTimeout(function() {
    console.log("2번 코드");
    
    setTimeout(function() {
      console.log("3번 코드");
    }, 1000);
  }, 2000);
}

CallbackFunc();
// 실행 결과 : 1번 코드 -> 2번 코드 -> 3번 코드

그러나 콜백 함수가 증가할수록 함수 안에 또 다른 함수를 계속 추가해야 한다. 이런 형태를 콜백 지옥이라고 한다. 콜백 함수를 여러 번 사용할수록 코드가 더 지저분해진다는 단점이 있다.
-> 이를 개선하기 위해 나온 것이 promise & thenasync & await이다.



📌 Promise then 사용하기

promise는 콜백 함수와 같이 비동기적으로 동작하는 코드를 동기적으로 구현할 때 사용한다. 콜백 함수와 달리 코드 가독성을 높일 수 있고 예외 처리도 쉽게 할 수 있다.

위의 예제를 promise와 then을 이용해 해결하면 다음과 같다.

function CallbackFunc() {
  console.log("1번 코드");

  new Promise((resolve) => setTimeout(resolve, 2000))
  .then(() => {
    console.log("2번 코드");
  })
  .then(() => {
    console.log("3번 코드");
  })
}

CallbackFunc();



📌 Promise catch 사용하기

Promise의 상태가 대기, 이행, 거부 중 거부 상태가 됐을 때 catch 함수를 실행한다. 대기 상태의 Promise에 에러가 발생해 이행으로 상태 변화를 하지 못하는 경우다.

function CallbackFunc() {
  new Promise((resolve, reject) => {
  	reject(Error("Error Info")) // reject 상태
  })
  .then(result => console.log("then " + result)) // 실행안됨
  .catch(result => console.log("catch " + result)) // catch Error: Error Info 출력.
}

CallbackFunc();
profile
모든게 새롭고 재밌는 프론트엔드 새싹
post-custom-banner

0개의 댓글