Developer_hong

4. React useEffect 본문

개인 프로잭트/react

4. React useEffect

Developer_hong 2022. 11. 23. 00:29
반응형

React에서는 useEffect를 사용하면 hook을 사용할 수 있다

-> 이전 리액트의 클래스형 컴포넌트에서 생명주기 메소드를 사용할 수 있었는데, 함수 컴포넌트에서도

useEffect를 사용하면 비슷하게 사용이 가능하다

-> 라이프 사이클 훅 componentDidMount, componentDidUpdate, componentWillUnmount와 비슷하게 대체 가능하다


useEffect의 기본 문법은 useEffect(effect, [, deps]); 

첫번째 인자로는 함수, 두번째 인자로는 배열을 넣어줄 수 있다

첫번째 인자로 전달된 함수는 컴포넌트가 랜더링된 이후에 실행이 되며

두번째 인자로 전달된 배열에 포함된 state 값이 있는 경우에만 첫번째 인자로 전달된 함수를 실행되도록 할 수 있다

 

ex)

useEffect(()=> {
    console.log('useEffect');
  })

 

ex)

useEffect(() => {

    console.log('useEffect');

}, [count])

 

useEffect에는 cleanup 함수가 있는데 return 함수를 통해 추가할 수 있고,

cleaup을 통해서 componentWillUnmount처럼 사용할 수 있다

ex) useEffect(() => {

        // 함수 처리

     return () => {

        // cleanup

      }

}, 배열);

 

-> 컴포넌트에 이벤트 리스너로 이벤트가 추가됐다면 컴포넌트가 언마운트 될 때 이벤트를 삭제해줘야 메모리 누수를 방지할 수 있다

( state 값 변경 등으로 인해서 다시 랜더링 되는 경우 계속해서 새로운 이벤트 리스너가 핸들러에 바인딩 될 수 있으므로)

 

이렇게 사용이 가능하며, 컴포넌트가 실행되면 useEffect가 실행된다

사용 방법은 아래의 예제를 보면 쉽게 이해가 가능하다


[ 컴포넌트 랜더링, useEffect 실행 ]

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

function App(){
  useEffect(()=> {
    console.log('useEffect !!!');
  })
  
  console.log('log !!!');

  return (
    <div className="App">
      <h1>useEffect Test</h1>
    </div>
  );
}

exprot default App;

다음과 같이 function App() 컴포넌트가 랜더링 될 때 console.log('useEffect'); 가 실행된다

App 컴포넌트가 랜더링 되면서 log !!! 가 출력되고, 이후에 useEffect가 실행되면서 useEffect!!! 출력

-> 실행 결과

log !!!

useEffect !!!


[ 컴포넌트 랜더링, state 변경으로 다시 랜더링 되는 경우 ]

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

function App(){
  const [count,setCount] = useState(0);

  useEffect(()=> {
    console.log(count);
  })

  const increase = () => {
    setCount(count + 1);
    console.log('count(+) 버튼 클릭 !!!');
  };

  return (
    <div className="App">
      <button onClick = {increase}> count + </button>
    </div>
  );
}

exprot default App;

 

처음 App 컴포넌트가 랜더링 된 이후에 useEffect가 한번 실행이 된다.

그 이후 button을 클릭하여 increase 함수가 실행되면

useState로 선언된 count가 증가한다

즉 state 변경이 생기면 React는 컴포넌트를 다시 랜더링 하므로 useEffect가 한번 더 실행된다

-> 실행 결과

0

count(+) 버튼 클릭 !!!

1

count(+) 버튼 클릭 !!!

2

count(+) 버튼 클릭 !!!

3


[ 컴포넌트 랜더링, 다양한 state가 존재하여 다시 랜더링 되는 경우 ]

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

function App(){
  const [count,setCount] = useState(0);
  const [price,setPrice] = useState(0);

  useEffect(()=> {
    console.log(count);
  })

  const increase = () => {
    setCount(count + 1);
    console.log('count(+) 버튼 클릭 !!!');
  };

  return (
    <div className="App">
      <button onClick = {increase}> count + </button>
      <button onClick = {()=> {
        setPrice(price + 100);
        console.log('price(+) 버튼 클릭 !!!');
      }}> price + </button>
    </div>
  );
}

exprot default App;

 

useState로 2개의 state ( count 와 price)를 만들고 price를 증가시키는 버튼을 누르게 되면

price가 변경이 되어 state가 바뀌므로 App 컴포넌트가 다시 랜더링된다

비록 count 는 변경된 것이 없지만 컴포넌트의 랜더링으로 useEffect가 실행이 돼서 count 값인 0이 버튼 누를 때 마다 출력된다

-> 실행 결과

0

price(+) 버튼 클릭 !!!

0

price(+) 버튼 클릭 !!!

0

price(+) 버튼 클릭 !!!

0


[ 컴포넌트 랜더링, 다양한 state가 존재하여 다시 랜더링 되지만, 특정 state에만 useEffect 실행하는 방법 ]

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

function App(){
  const [count,setCount] = useState(0);
  const [price,setPrice] = useState(0);

  useEffect(()=> {
    console.log(count);
  }, [count])

  const increase = () => {
    setCount(count + 1);
    console.log('count(+) 버튼 클릭 !!!');
  };

  return (
    <div className="App">
      <button onClick = {increase}> count + </button>
      <button onClick = {()=> {
        setPrice(price + 100);
        console.log('price(+) 버튼 클릭 !!!');
      }}> price + </button>
    </div>
  );
}

exprot default App;

useEffect의 두번째 인자로 count라는 state를 전달해줘서 

price + 버튼을 눌러서 price state가 변경이 되더라도 useEffect는 count state 값이 바뀌지 않았으므로 실행되지 않는다

-> 실행결과

0

price(+) 버튼 클릭 !!!

price(+) 버튼 클릭 !!!

price(+) 버튼 클릭 !!!


[ 컴포넌트 랜더링, 다양한 state가 존재하여 다시 랜더링 되지만, 여러개의 특정 state에만 useEffect 실행하는 방법 ]

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

function App(){
  const [count,setCount] = useState(0);
  const [price,setPrice] = useState(0);

  useEffect(()=> {
    console.log(count);
  }, [count, price])

  const increase = () => {
    setCount(count + 1);
    console.log('count(+) 버튼 클릭 !!!');
  };

  return (
    <div className="App">
      <button onClick = {increase}> count + </button>
      <button onClick = {()=> {
        setPrice(price + 100);
        console.log('price(+) 버튼 클릭 !!!');
      }}> price + </button>
    </div>
  );
}

exprot default App;

useEffect의 두번째 인자로 count, price 모두 지정한 결과

버튼 클릭으로 price 와 count state가 변경돼서 재랜더링 될 때 마다 useEffect가 실행된다

-> 실행결과

0

price(+) 버튼 클릭 !!!

0

count(+) 버튼 클릭 !!!

1

count(+) 버튼 클릭 !!!

2

price(+) 버튼 클릭 !!!

2

price(+) 버튼 클릭 !!!

2


[ useEffect를 처음 랜더링했을 때 1회만 실행하고싶을 경우 ]

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

function App(){
  const [count,setCount] = useState(0);
  const [price,setPrice] = useState(0);

  useEffect(()=> {
    console.log(count);
  }, [count, price])

  useEffect(()=> {
    console.log('Run Once');
  }, [])

  const increase = () => {
    setCount(count + 1);
    console.log('count(+) 버튼 클릭 !!!');
  };

  return (
    <div className="App">
      <button onClick = {increase}> count + </button>
      <button onClick = {()=> {
        setPrice(price + 100);
        console.log('price(+) 버튼 클릭 !!!');
      }}> price + </button>
    </div>
  );
}

exprot default App;

useEffect(()=> { console.log('Run Once'); }, [])

useEffect의 두번째 인자로 빈 배열을 전달하여 컴포넌트가 최초 랜더링 됐을 때 한번만 실행 시킬 수 있다

-> 실행결과

0

Run Once

count(+) 버튼 클릭 !!!

1

count(+) 버튼 클릭 !!!

2


반응형

'개인 프로잭트 > react' 카테고리의 다른 글

2. React 기초, 설명  (0) 2022.10.17
1. 개발환경 세팅 (React + TypeScript)  (0) 2022.08.23