컴포넌트(4) 리액트 훅(react hook)사용 - useEffect
useEffect란?
- 컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook이다.
- useEffect 이후에(마운트 해제되는 때) clean-up (정리)를 실행할 수 있다.
기본형태
// 첫 번째 인자로는 effect 함수, 두 번째 인자로는 dependency array
useEffect(() => {
console.log('useEffect가 실행되면서 렌더링.')
// effect 이후에 어떻게 정리(clean-up)할 것인지 표시
return () => {
....
// useEffect 종료되면 실행.
}
}, []) // 빈 배열을 입력하는 경우 렌더링 될 때 마다 실행
App.js
import Main from './component/Main';
import './App.css';
function App() {
return (
<div className="App">
<Main/>
</div>
);
}
export default App;
예제 1. componentDidMount() & componentDidUpdate() 를 표한하기
useEffect(() => {
// 수행할 함수
});
src/component/Main.js
import React, { useState, useEffect } from "react";
const Main = () => {
const [count, setCount] = useState(0);
const countUp = () => setCount(count + 1);
useEffect(() => {
console.log("useEffect => ", count);
});
return (
<div>
<p>{count}번 클릭!</p>
<button onClick={countUp}>클릭하기</button>
</div>
);
};
export default Main;
#결과
렌더링이 되고, count 스테이트가 변경될 때 마다 console.log가 찍힌다.
예제 2. jquery의 $( document ).ready(function() { } 와 유사한 표현
useEffect(() => {
// 수행할 함수
}, 빈배열)
src/component/Main2.js
import React, { useState, useEffect } from "react";
const Main2 = () => {
const [count, setCount] = useState(0);
const countUp = () => setCount(count + 1);
useEffect(() => {
console.log("useEffect => ", count);
},[]);
return (
<div>
<p>{count}번 클릭!</p>
<button onClick={countUp}>클릭하기</button>
</div>
);
};
export default Main2;
#결과
위의 예시와는 다르게, 최초 렌더링 시에만 console.log가 출력된다.
예제3. 특정값이 변경될때만 실행
useEffect(() => {
// 수행할 함수
}, 특정배열);
src/component/Main3.js
import React, { useState, useEffect } from "react";
const Main3 = () => {
const [count, setCount] = useState(0);
const countClick = () => setCount(count + 1);
useEffect(() => {
console.log("useEffect print count => ", count);
}, [count]);
return (
<div>
<p>{count}번 클릭!</p>
<button onClick={countClick}>클릭하기</button>
</div>
);
};
export default Main3;
#결과
useEffect 함수 배열 인자에 count를 넣고 count의 값이 변경되면 log가 출력된다.
예제 4. 배열인자에 여러 state 넣고 출력해보기
src/component/Main4.js
import React, { useState, useEffect } from "react";
const Main3 = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState("Dev.MK");
const countClick = () => setCount(count + 1);
const handleChangeName = (e) => setName(e.target.value);
useEffect(() => {
console.log("useEffect print count => ", count);
console.log("useEffect print name => ", name);
}, [name,count]);
return (
<div>
<p>안녕하세요. {name} 입니다.</p>
<input onChange={handleChangeName} />
<p>{count}번 클릭!</p>
<button onClick={countClick}>클릭하기</button>
</div>
);
};
export default Main3;
#결과
name값과 count값이 실시간으로 변경될 때 마다 log가 출력된다.
cleanup 함수란?
- useEffect 안에서 return 할 때 실행 된다.(useEffcet의 뒷정리를 한다.)
- 만약 컴포넌트가 마운트 될 때 이벤트 리스너를 통해 이벤트를 추가하였다면 컴포넌트가 언마운트 될 때 이벤트를 삭제 해주어야 한다. 그렇지 않으면 컴포넌트가 리렌더링 될 때마다 새로운 이벤트 리스너가 핸들러에 바인딩 될 것이다. 이는 자주 리렌더링 될 경우 메모리 누수가 발생할 수 있다.
// 첫 번째 인자로는 effect 함수, 두 번째 인자로는 dependency array
useEffect(() => {
console.log('useEffect가 실행되면서 렌더링.')
// effect 이후에 어떻게 정리(clean-up)할 것인지 표시
return () => {
....
// useEffect 종료되면 실행.
}
}, []) // 빈 배열을 입력하는 경우 렌더링 될 때 마다 실행
예제 5. clean-up 영역에 log 출력하기
src/component/Main4.js
import React, { useState, useEffect } from "react";
const Main4 = () => {
const [count, setCount] = useState(0);
const countClick = () => setCount(count + 1);
useEffect(() => {
console.log("useEffect print count => ", count);
return () => {
console.log("useEffect cleanup count => ", count);
}
}, [count]);
return (
<div>
<p>{count}번 클릭!</p>
<button onClick={countClick}>클릭하기</button>
</div>
);
};
export default Main4;
#결과
- 클릭시 cleanup 함수에서는 이전 count값, 그리고 렌더링 후 변경된 count값이 출력
- useEffect가 실행되기 전 return 함수(clean-up)를 먼저 실행한다.
- componentWillUnmount() 역할을 할 수 있다.
예제 6. 타이머프로그램 만들기
src/component/Timer.js
import React, { useEffect }from 'react';
const Timer = (props) => {
useEffect(() => {
const timer = setInterval(() => {
console.log('타이머 진행중....');
}, 1000);
// clean-up
return () => {
clearInterval(timer);
}
}, [])
return(
<div>
<span>타이머 시작.</span>
</div>
)
}
export default Timer;
App.js
import { useState } from 'react'
import Timer from './component/Timer';
import './App.css';
function App() {
const [showTimer, setShowTimer] = useState(false);
return (
<div className="App">
<header className="App-header">
{showTimer && <Timer/>}
<button onClick={() => setShowTimer(!showTimer)}>토글 타이머</button>
</header>
</div>
);
}
export default App;
# 결과 - 타이머 시작
log가 1초마다 출력된다.
# 결과 - 타이머 종료
다시 버튼을 누르면 타이머가 종료되는 것을 볼 수 있다.
clean-up 리턴안에 clearInterval를 함수하여 타이머를 초기화 시킨것을 볼 수 있다.
출처
https://goddaehee.tistory.com/308
https://itprogramming119.tistory.com/entry/React-useEffect-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C