Mount(화면에 첫 렌더링), Update(다시 렌더링), Unmount(화면에서 사라질때) 될때 특정 작업을 처리할 코드를 실행시키고 싶다면 useEffect사용
useEfect(() => {})
기본적으로 useEffect hook은 인자로 callback함수를 받음
callback함수란 다른 함수의 인자로 전달된 함수를 의미
callback 함수 내부에 우리가 원하는 작업을 처리해줄 코드를 작성
useEffect(() => {//작업...})
1️⃣ useEffect(() => {//작업...}); //useEffect의 인자로 하나의 callback 함수만 받음
2️⃣ useEffect(() => {//작업}, [value]); //useEffect의 첫번째 인자로 callback함수,
//두번째 인자로 배열을 받음(이 배열을 다른말로 dependency array라고 함)
1️⃣ useEffect(() => {//작업...});
//특징: 렌더링 될때 마다 매번 callback 실행
//컴포넌트가 맨처음 화면에 렌더링이 될때, 컴포넌트가 다시 렌더링 될때 실행
2️⃣ useEffect(() => {//작업...}, [value]);
//특징: 화면에 첫 렌더링이 될때 실행
// 배열안에 value값이 바뀔때만 실행
// 빈배열 전달시, 화면에 첫 렌더링 될때 실행
useEffect(() => {//구독...}, []);
• 만약 useEffect에서 어떤 서비스를 구독하는 코드를 넣었다면,
• 이후 '구독해제'를 하는 clean up 정리 작업을 처리 해줘야함
• 만약 타이머를 시작했다면, 더이상 타이머를 사용할 필요가 없을때 타이머를 멈추는 정리 작업을 해줘야함
• 만약 이벤트 리스너를 등록했다면, 등록한 리스너를 제거 해주는 정리 작업을 해야함
//이걸 정리하려면 useEffect에 return값으로 함수 추가
//함수 안에서 우리가 원하는 정리하는 작업을 처리해주면 됨
// 이렇게 함수를 return을 해주면 해당 컴포넌트가 unmount 될때, 혹은 다음 렌더링시 불릴 useEffect가 실행되기 이전에 그 함수가 실행
useEffect(() => {//구독...
return () => {
//구독해지...
}
},[]);
import React, {useState, useEffect} from 'react';
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleInputChange = (e) => {
setName(e.target.value);
}
useEffect(() => {
//..여기 들어가는 callback 안에 들어가는 부분은 우리의 컴포넌트가 렌더링 될때마다 매번 실행
console.log('렌더링🍎')
})
return (
<div>
<button onClick={handleCountUpdate}>Update</button> //업데이트 버튼
<span>count: {count} </span> //현재 카운트가 몇개인지 보여주는 span태그
<input type="text" value={name} onChange={handleInputChange}/>
<span>name: {name}</span>
</div>
);
}
//input안에 값이 업데이트 될때마다 handleInputChange라는 함수가 불림 → 그리고 그 안에
//있는 setName이 불림 → 그러면 name state안에 있는 값이 계속해서 업데이트 됨 → 입력할때마다 계속 렌더링 됨 →
//그러면 useEffect 안에 있는 callback이 계속 불림 →그러면 계속 렌더링되니까 무거워짐
export default App;
import React, {useState, useEffect} from 'react';
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleInputChange = (e) => {
setName(e.target.value);
}
//만약 name의 업데이트는 무시하고 count가 업데이트 될때만 useEffect를 실행하고 싶다면?
//→ useEffect의 두번째 인자로 배열을 주면 됨
c
useEffect(() => {
console.log('count 변화 🍎')
}, [count]); //배열안에는 count를 주면 됨
// -> 이렇게 두번째 인자로 배열을 주게 되면 맨처음 컴포넌트가 렌더링됐을 때, count가 업데이트 됐을때만 실행
// 마운트 + [name] 변경될때만 실행!
useEffect(() => {
console.log('name 변화 🍎')
}, [name]);
// 렌더링 마다 매번 실행, 렌더링 이후
useEffect(() => {
console.log('렌더링 🍎')
});
// useEffect를 맨처음 화면에 렌더링(mount) 될때만 실행하고 싶으면 2번째 인자로 빈배열!
useEffect(() => {
console.log('마운팅 🍎')
}, []);
return (
<div>
<button onClick={handleCountUpdate}>Update</button>
<span>count: {count} </span>
<input type="text" value={name} onChange={handleInputChange}/>
<span>name: {name}</span>
</div>
);
}
export default App;
//Timer component
import React, {useEffect} from 'react';
const Timer = (props) =>{
useEffect(() => { //Timer component가 맨처음 화면에 렌더링 됐을때만 실행
const timer = setInterval(() => {
console.log("타이머 돌아가는 중");
}, 1000);//1초마다 한번씩 반복
return () => {
//여기에 정리 작업을 해줄 코드를 넣어줌
//타이머 컴포넌트가 unmount될때, 화면에서 사라질때 실행
clearInterval(timer); // 인자로 우리가 만들어준 timer를 넣음(swtInterval을 끝내줌)
console.log('타이머가 종료됐습니다');
}
}, []);
return(
<div>
<span>타이머를 시작합니다. 콘솔을 보세요!</span>
</div>
);
//이렇게 작성하면 타이머가 브라우저에 맨처음 마운팅 됐을때만 useEffect 내부의 callback함수 실행(setInterval의 인자로 들어간 callback을 1초마다 반복해서 부름)
};
import React, {useState, useEffect} from 'react';
import Timer from './component/Timer';
function App() {
const [showTimer, setShowTimer] = useState(false);
return (
<div>
{showTimer && <Timer />}//showTimer가 true일때만 실행
<button onClick={() => setShowTimer(!showTimer)}>Toggle Timer</button> //이 버튼이 클릭될때마다 showTimer가 flase라면 true로 바껴야 하고
//true면 false로 바껴야함. 그래서 onClick에 반전값을 줌
</div>
);
}
export default App;