Written by
Parkdev
on
on
React 라이프사이클 (useEffect)
# Lifecycle과 useEffect
- 컴포넌트의 lifecycle이란?
- 컴포넌트가 페이지에 보이는 순간 장착된다. (mount)
- 업데이트가 되는 과정도 있다. (update)
- 필요없으면 제거되기도한다 (unmount)
- 이렇게 컴포넌트의 상태에 따라 변경되는 상태를 lifecycle이라고한다.
- 이렇게 컴포넌트의 상태가 변경할때 중간 중간에 코드를 실행가능하다
- 이것을 통해 다양한 응용이 가능하다
예제)
// 예전 형식 (class 사용하는 형식)
class Detail2 extends React.Compoenent {
componentDidMount() {
//마운트시 실행
}
compoenetDidUpdate {
//업데이트시 실행
}
compoenetWillUnmount(){
// 언마운트시 실행
}
}
// 최신 형식
function Detail(props) {
//mount, update시 코드를 싱행해주는 useEffect
useEffect(()=>{
console.log('안녕')
})
... 본문
}
-
근대사실 useEffect를 사용하지않고 실행해도 update마다 실행된다. => 왜 사용하는가?
-
실행 시점이 다르다. (html랜더링이 다 된 이후에 실행된다.)
-
예상되는 응용방법
-
로딩 완료후 로딩 화면을 제거하려고 할때?
-
시간이 오래걸리는 작업을 나중에 실행하고 싶을때
- 오래걸리는 계산
- 서버에서 데이터 불러오는 작업
- 타이머
for (var i = 0; i <, 10000; i++){ console.log(1) } //이런 함수가 2초 이상 걸린다고 할때 useEffect안에 넣는다면 // 페이지를 우선 다보여주고 // 그다음 시간이 오래걸리는 위작업이 진행되어 페이지 보기의 효율성을 높일 수 있다.
-
이러면 사용자에게 화면을 좀더 빨리(효율적으로) 보여줄 수 있다.
-
-
-
-
왜 이름이 Effect
- side effect에서 따온 함수명
- 함수의 핵심과 관계없는 부가기능 들
예제
- 아래 박스를 페이지 로딩 이후 2초 뒤에 사라지게 만들어보자
<div className="alert alert-warning">
2초이내 구매시 할인
</div>
- 내가 작성한 코드
useEffect(()=> {
setTimeout(()=>{ document.getElementById("Event").style.display = 'none' }, 2000)
})
...본문...
<div id="Event" className="alert alert-warning">
2초이내 구매시 할인
</div>
- 조금더 리엑트스럽게 만들어보자
useEffect(()=> {
setTimeout(()=> { setAlert(false) }, 2000)
})
let [alert,setAlert] = useState(True)
...본문...
{
alert ? <div className="alert alert-warning">
2초이내 구매시 할인
</div> : null
}
심화
useEffect()의 맨마지막에 [실행조건]
을 넣으면 정확한 시점을 지정할 수 있다.
useEffect(()=> {
setTimeout(()=> { setAlert(false) }, 2000)
}, [count]) // count변수가 변경될때마다 실행
- 단 마운트 시에는 기본적으로 한번 실행된다.
응용
- 다음과 같이 작성하면 마운트 시에만 실행되도록 설정할 수 있다.
useEffect(()=> {
setTimeout(()=> { setAlert(false) }, 2000)
}, []) // array를 빈칸으로하면 된다.
- useEffect에 return값을 지정가능하다 (Clean up function)
- 이러면 useEffect동작 전에 실행된다.
useEffect(()=> {
let a = setTimeout(()=> { setAlert(false) }, 2000)
return ()= {
//코드를 작성하면 이 코드는 UseEffect 동작 전에 실행된다.
//ex) 기존 타이머는 제거해주세요
//타이머를 변수에 담아두고 삭제하면된다.
clearTimeout(a)
}
}, [])
- 이러한 기능은 데이터를 요청하는 코드에서 특히 유용하다.새로고침하면서 화면이 계속 마운트 되면서 충돌이일어나거나 버그가 생성될 수 있기때문에 항상 유념해두자
useEffect(()=> {
// 데이터 불러오는 함수
return ()= {
// 기존 데이터 요청을 제거하는함수
}
}, []) //[]을 통해 mount시에만 실행되게끔
- Cleanup function은
mount
시에는 실행이 안되지만,unmount
시에는 한번 실행된다.
요약
1. useEffect(()=>{코드작성}) | 재랜더링 마다 실행하고싶을때
2. useEffect(()=>{코드작성}, []) | mount시에 1회 실행하고 싶으면
3. useEffect(()=>{코드작성
return () => {
//cleanup function 작성
}
}, []) | unmount시 1회 실행하고 싶을때 실행하고싶을때
예제
useEffect를 이용해서 숫자 이외의 값이 들어오면 Alert를 표시하는 인풋을 만들어보자
- 완성한 코드 코드
let [value, setValue] = useState('')
let [textAlert, setTextAlert] = useState(false)
useEffect(() => {
isNaN(value)? setTextAlert(true) : setTextAlert(false);
}, [value])
return(
{
textAlert ? <p className="col text-danger">숫자만 입력해주세요</p> : null
}
</div>
<input type="text" className="col form-control red" placeholder="숫자 입력" onChange={ (e) => setValue(e.target.value)} />
</div>
)