ygreenb
yellowgreenblue
ygreenb
전체 방문자
오늘
어제
  • TIL (130)
    • Algorithm & Data Structure (70)
      • 이론 (4)
      • 프로그래머스 (54)
      • 백준 (12)
    • JAVA (4)
    • Android Studio (9)
    • Database (1)
    • WEB (25)
      • HTML+CSS (7)
      • Javascript (5)
      • React (11)
      • Django (1)
      • Node.js (1)
    • Computer Vision (13)
    • Git (8)

블로그 메뉴

  • HOME
  • TAG
  • GITHUB

공지사항

인기 글

태그

  • dfs
  • BFS
  • 스택/큐
  • kotiln
  • reactjs
  • sort
  • entrySet
  • stack
  • 코틀린
  • DP
  • PriorityQueue
  • getOrDefault
  • Queue
  • HashMap
  • React
  • Comparator
  • 안드로이드
  • java
  • 프로그래머스
  • greedy
  • Arrays.sort()
  • 프로그래머스 Lv.2
  • git
  • git bash
  • 해시
  • 깃
  • Android
  • 깃허브
  • compareTo()
  • 백준

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ygreenb

yellowgreenblue

WEB/React

[React] Effects (useEffect, clean-up)

2022. 1. 29. 01:15

Intro

  • useEffect
  • Clean-up

예를 들어, 우리가 검색 api를 사용하려고 할 때 맨 처음 api를 호출해 데이터를 받아온다. 하지만 이후에 버튼을 클릭하든.. 어떤다 state가 변경될때마다 다시 그 api를 또 호출한다면? 매우 비효율적이다.

그래서 우리는 가끔은 특정 코드들이 처음 한번만. 즉 첫번째 컴포넌트의 render에만 실행되도록 하고 나중에 state가 변하더라도 그 코드들을 다시 실행되지 않도록 하고 싶다.

 

useEffect function

React에게 컴포넌트가 렌더링 이후에 어떤 일을 수행할지를 알려주는데, 아래의 예시처럼 특정 코드들을 특정한 때에만 실행되도록 하고 싶을때 사용할 수 있다.

useEffect 함수는 두 개의 인자(argument)를 가지고 있다.

useEffect(()=>{},[특정변수 혹은 오브젝트]);


첫 번째 인자는 우리가 실행시키고 싶은 코드(보통 함수를 넘겨주고 이 함수를 'effect'라고 부름)이고,
두 번째 인자는 dependencies로 react.js가 지켜보아야하는 것으로 그것들이 변화할 때, react.js가 코드를 실행시킨다. (인자에 리스트가 존재하면, 해당 리스트의 값이 변화될 때만 실행된다.)

두 번째 인자에 빈 배열 []을 주게되면(비어있다면_, react.js 가 지켜볼 대상(dependency)이 없기 때문에 코드가 한 번만 실행될 거라는 걸 의미한다. 즉, 변화에 대해 반응하지 않고 최초 렌더링 혹은 컴포넌트 해제 시 호출이 된다.  또한 배열을 넣어줄 수 있기 때문에 지켜볼 대상(특정변수 혹은 오브젝트)을 하나만 넣어주거나 여러 개를 넣어 줄 수도 있다.

  useEffect(() => {
    console.log("I run only once."); // 시작할 때 한번만 실행
  }, []);
  useEffect(() => {
    console.log("I run when 'keyword' changes."); // 시작할 때 + keyword 변화시 실행
  }, [keyword]);
  useEffect(() => {
    console.log("I run when 'counter' changes."); // 시작할 때 + counter 변화시 실행
  }, [counter]);
  useEffect(() => {
    console.log("I run when 'keyword & counter' changes."); // 시작할때 + keyword, counter 둘 중 변화시 실행
  }, [keyword, counter]);

 

Cleanup function

우리는 컴포넌트가 파괴(destroy)될 때 무언가를 하도록 하고 싶은 경우가 있다. ( 함수를 실행시킨다던지 데이터를 반환한다던지 등...)
useEffect는 컴포넌트의 렌더링 이후에 다양한 side effects를 표현할 수 있는데, effect에 정리(clean-up)가 필요한 경우에는 함수를 반환(return)해주면 된다.

React는 컴포넌트가 마운트 해제되는 때에 정리(clean-up)을 실행한다.
하지만 effect는 한번이 아니라 렌더링이 실행되는 때마다 실행되는데, React가 다음 차례의 effect를 실행하기 전 이전의 렌더링에서 파생된 effect를 정리하는 이유가 바로 이 때문이다.

React가 DOM을 업데이트 한 뒤 추가로 코드가 실행할 필요가 없으면 정리를 해줘야한다.
버튼을 누름으로써 Hello라는 문구가 보이고 사라지게하는 어플리케이션을 만들어보려고 한다. 여기서, 텍스트를 반환하는 Hello 컴포넌트는 더 이상 사용하지 않는 컴포넌트이기 때문에 해제해야 한다. 그렇지 않으면 메모리 누수가 발생해 시스템에 안좋은 영향을 미칠 수 있기 때문이다.


초기 렌더링 시 showing이라는 state 값이 true일 시 Hello 컴포넌트를 보여주고, false일 시 컴포넌트를 보여주지 않도록 한다. 이 어플리케이션의 동작원리는 다음과 같다.

  1. 맨 처음에 App 컴포넌트 렌더링 : showing값 false, Show 버튼만 출력
  2. Show 버튼을 클릭 => 클릭이벤트가 발생(showing값 false=>true) => state 값이 변경되었으니 App 컴포넌트 리렌더링 => Hello 컴포넌트 생성 => useEffect 함수 effect인 hiFn 함수 실행(created 로그) => Hello와 Hide 버튼 출력
  3. Hide 버튼을 클릭 => 클릭 이벤트가 발생(showing값이 true=>false) => state 값 변경되었으니 App 컴포넌트 리렌더링 => 이 전의 Hello 컴포넌트의 effect 클린업(bye 로그) => Show 버튼만 출력
import { useEffect, useState } from "react";

function Hello() {
  function byFn() {
    console.log("bye :(");
  }
  function hiFn() {
    console.log("created :)");
    return byFn; // component가 파괴될때 function을 실행하고 싶으면, 새로운 function을 return해야함
  }
  useEffect(hiFn, []);
  return <h1>Hello</h1>;
}
function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => setShowing((prev) => !prev);
  return (
    <div>
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}

export default App;

위 코드는 좀 복잡한 편이고, 보통은 useEffect 안에 모든 코드를 작성한다.
일반적인 함수로 정의하든, 화살표 함수로 정의하든 결과는 똑같다.

function Hello() {
  useEffect(() => {
    console.log("hi :)");
    return () => console.log("bye :("); // function 리턴
  }, []);
  return <h1>Hello</h1>;
}
function Hello() {
	useEffect(function (){
		console.log("hi :)");
		return function(){
			console.log("bye :(");
 		}
 	}, []);
	return <h1>Hello</h1>;
}

실행결과는 다음과 같다.

 

 

저작자표시 (새창열림)

'WEB > React' 카테고리의 다른 글

[React] API 사용하기  (0) 2022.02.02
[React] 배열 State  (0) 2022.02.02
[React] Props (Memo, Props Types)  (0) 2022.01.28
[React] State  (0) 2022.01.28
[React] Component, JSX  (0) 2022.01.26
    'WEB/React' 카테고리의 다른 글
    • [React] API 사용하기
    • [React] 배열 State
    • [React] Props (Memo, Props Types)
    • [React] State
    ygreenb
    ygreenb
    개발공부기록장

    티스토리툴바