지지난 포스트에서
useEffect(()=>{
setTimeout(()=>{ setAlert(false) }, 2000)
}, [])
여기 마지막에 붙은 대괄호를 보았을 것이다.
저 대괄호의 용도는 뭐지?
useEffect(()=>{ 실행할코드 }, [count])
useEffect()의 둘째 파라미터로 대괄호를 넣을 수 있는데 거기에 변수나 state같은 것들을 넣을 수가 있다.
그렇게 하면 [ ]에 있는 변수나 state가 변할 때만 useEffect 안의 코드를 실행해준다.
그러므로 위의 코드는 count라는 변수가 변할 때만 useEffect 안의 코드가 실행시킬 것이다.
*[ ] 안에 state는 여러개 넣을 수 있다.
useEffect(()=>{ 실행할코드 }, [])
위처럼 아무것도 넣지 않으면 컴포넌트 mount시 (로드 시) 1회 실행하고 영영 실행해주지 않는다.
▶[ ]가 없을 때
count state(노란색 버튼을 누르면 +1이 됨)가 변하든 말든 console창에 렌더링이라는 글자가 찍히지 않는다.
▶[ ]가 있을 때
count state(노란색 버튼을 누르면 +1이 됨)가 변하면 console창에 렌더링이라는 글자가 찍힌다.
이해 완료! 이제 다른 기능을 배워보자
useEffect 동작하기 전에 특정코드를 실행하고 싶으면 return ()=>{} 안에 넣을 수 있다.
useEffect(()=>{
그 다음 실행됨
return ()=>{
여기있는게 먼저실행됨
}
}, [count])
useEffect 안에 있는 코드를 실행하기 전 return ()=>{ } 안에 있는 코드를 실행해줌.
이걸 언제 쓰면 좋으냐?
예를 들어 setTimeout 타이머를 쓴다고 가정하면 setTimeout() 쓸 때마다 브라우저 안에 타이머가 하나 생긴다.
근데 useEffect 안에 썼기 때문에 컴포넌트가 mount 될 때 마다 실행된다.
그럼 잘못 코드를 짜면 타이머가 100개 1000개 생길 수도 있게 되고
이런 버그를 방지하기 위해 useEffect에서 타이머 만들기 전에 기존 타이머를 싹 제거하라고 코드를 짤 수 있다.
useEffect(()=>{
let a = setTimeout(()=>{ setAlert(false) }, 2000)
return ()=>{
clearTimeout(a)
}
}, [])
참고1. clean up function에는 타이머제거, socket 연결요청제거, ajax요청 중단 이런 코드를 많이 작성한다.
참고2. 컴포넌트 unmount 시에도 clean up function 안에 있던게 1회 실행된다.