<옛날 방식>
class Detail extends React.Component {
componentDIdMount() {
}//컴포넌트 mount시 이 코드 실행
componentDIdUpdate() {
}//컴포넌트 update시 이 코드 실행
componentDIdUNmount() {
}//컴포넌트 unmount시 이 코드 실행
}
<달라진 방식>
import { useEffect } from "react";
//생략
function Detail(props) {
useEffect(()=>{
// 컴포넌트가 mount, update시 이 코드 실행됨
// console.log('hello')로 실험해보기
})
}
작은 팁) console.log('hello')을 쳐보면 두번 출력된다. (사이트에서는 한번 동작) 이는 리액트상에서 디버깅을 위해 이렇게 동작 되는데 이게 싫으면 index.js파일에서 <React.StrictMode>를 제거 하면 된다.
import { useEffect } from "react";
//생략
function Detail(props) {
useEffect(()=>{
// 컴포넌트가 mount, update시 이 코드 실행됨
console.log('hello')
})
let [count, setCount] = useState(0)
return (
//생략
<button onClick={()=>{setCount(count+1)}}>버튼</button>
//버튼 클릭 시 재랜더링 -> 재랜더링 할 때마다 'hello' 찍히게 됨
)
}
useEffect는 html 렌더링 후에 동작한다.
즉 위의 코드를 보면 Detail함수 안에 html(return 아래 코드들)이 다 렌더링 된 후, useEffect안에 코드가 실행된다.
이처럼 usEffect는 html이 렌더링 된 후 실행되므로, 시간이 오래 걸릴 수 있는 어려운 코드를 useEffect로 빼서 넣어주면 html 렌더링 시간을 단축 할 수 있다. 따라서 사용자에게 빠른 렌더링을 보여줄 수 있다.
: useEffect 실행조건 넣을 수 있는 곳
let [alert, setAlert] = useState(ture);
useEffect(()=>{
setTimeout(()=>{ setAlert(false) }, 2000)
}, []) //[]안에 useEffect 실행조건을 넣는다.
원래는 mount, update 시 useEffect 코드가 실행 되었는데,
[]이면, mount시에만 코드가 실행 된다.(update시 실행되지 않음)
=> 컴포넌트 mount시 1회만 실행시키고 싶으면 dependency를 []을 이용하면 된다.
[]에 변수를 넣어주면 mount시, []안에 변수의 state가 변할 때 실행 된다.
let [alert, setAlert] = useState(ture);
useEffect(()=>{
//let a =
setTimeout(()=>{ setAlert(false) }, 2000)
return ()=>{
// 예시) 기존 타이머는 제거해주세요
// 예시) clearTimeout(a) // 타이머 제거해주는 함수
}
}, []) // return 추가 가능
clean up function
: useEffect 안 return문 안에 코드
useEffect가 실행이 되기 전에 코드를 실행 하고 싶다면, useEffect 안에 return()=>{} 코드를 추가하여 먼저 실행시키고 useEffect 동작 시킬 수 있다.
예시) 타이머를 장착해준다 생각할 때, 타이머가 재렌더링 될 때 마다 실행되는 것을 방지하기 위해 return문 안에 전에 생성한 타이머를 제거하는 함수코드를 작성해주어야 한다.
: 업데이트 시 생성된 타이머 제거 후 (clean up function 실행 후) -> 새로운 타이머 장착(useEffect 안의 코드 실행)