공부방
LifeCycle / useEffect 본문
컴포넌트의 LifeCycle
- 생성(mount)
- 재렌더링(update)
- 삭제(unmount)
LifeCycle Hook
- 컴포넌트 등장 전에 or 컴포넌트 사라지기 전에 or 컴포넌트 업데이트 되고 나서 등으로 코드를 실행할 수 있다.
- 위의 그림처럼 갈고리를 달아서 코드를 넣어주면 된다.
- 갈고리를 영어로 hook이라고 하기 때문에 LifeCycle Hook이라고 부름
옛날 React에서 LifeCycle hook 쓰는 법
class Detail2 extends React.Component {
componentDidMount(){
//Detail2 컴포넌트가 로드되고나서 실행할 코드
}
componentDidUpdate(){
//Detail2 컴포넌트가 업데이트 되고나서 실행할 코드
}
componentWillUnmount(){
//Detail2 컴포넌트가 삭제되기전에 실행할 코드
}
}
- class 문법으로 컴포넌트를 만들었음
요즘 React LifeCycle hook 쓰는 법
import {useState, useEffect} from 'react';
function Detail(){
useEffect(()=>{
//여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
console.log('안녕')
});
let [count, setCount] = useState(0)
return (
<button onClick={()=>{ setCount(count+1) }}>버튼</button>
)
}
- 상단에서 useEffect import 해옴
- 콜백함수 추가해서 안에 코드 적으면 이제 그 코드는 컴포넌트가 mount, update시 실행
따라서 이게 LifeCycle hook - Detail 페이지 로드시 콘솔창에 '안녕' 출력
- 콘솔창에 안녕이 2번 출력된다.
=>index.js에 <React.StrictMode> 라는 태그가 있으면 2번 출력됨.
- 디버깅용으로 편하라고 2번 출력해주는데 싫다면 삭제해도 무방
- 콘솔창에 안녕이 2번 출력된다.
- 버튼을 누를 때마다 재렌더링되며 콘솔창에 안녕 출력
근데 useEffect 밖에 적어도 결과는 같다?
- 컴포넌트가 mount, update시 function 안에 있는 코드도 다시 읽고 지나가기 때문에 useEffect 바깥에 적어도 똑같이 컴포넌트 mount, update시 실행된다.
- useEffect 안에 적은 코드는 html 렌더링 이후에 동작하기 때문에 유용
function Detail(){
(반복문 10억번 돌리는 코드)
return (생략)
}
function Detail(){
(반복문 10억번 돌리는 코드)
return (생략)
}
- 첫번째 코드처럼 대충 안에 적는다면 반복문을 돌리고 난 후 html을 보여준다.
- 하지만 두번째 코드처럼 useEffect 안에 적는다면 html 보여주고 나서 반복문을 돌려준다.
- 이런 식으로 코드의 실행 시점을 조절할 수 있기 때문에 조금이라도 html 렌더링이 빠른 사이트를 원하면 오래걸리는 반복 연산, 서버에서 데이터 가져오는 작업, 타이머 다는 것들은 useEffect 안에 넣는게 효율적
응용 - 동적인 ui 만들기
컴포넌트 안에 박스를 하나 만들고 이 페이지에 방문 후 2초 후에 박스가 사라지게 하기
※ 그 전에 알아야 할 JS 문법 setTimeout
setTimeout( ()=>{ 1초 후 실행할 코드 }, 1000);
- 1000이라고 숫자 적은 곳에 ms 단위로 시간을 적어주면 된다.(1000이면 1초)
function Detail(){
let [alert, setAlert] = useState(true)
useEffect(()=>{
setTimeout(()=>{ setAlert(false) }, 2000)
}, [])
return (
{
alert == true
? <div className="alert alert-warning">
2초이내 구매시 할인
</div>
: null
}
)
}
- 큰 순서로 따지면 UI 상태를 저장할 state 만들기
- state에 따라서 UI가 어떻게 보일지 작성
- alert라는 state를 true로 바꾸면 노란박스가 보이고 false로 바꾸면 보이지 않는다.
- 이제 페이지 접속 후 2초 후에 저걸 안 보이게 하려면 useEffect와 setTimeout을 사용하여 2초 후에 state 값을 false로 바꾸면서 안 보이게 할 수 있다.
useEffect 뒤에 ,[ ] 에 대해 알아보자
useEffect에 넣을 수 있는 실행 조건
useEffect(()=>{ 실행할코드 }, [count])
- useEffect()의 둘 째 파라미터로 [ ]를 넣을 수 있다.
- 여기에 변수나 state 같은 것들을 넣을 수 있다.
- 그럼 [ ]에 있는 변수나 state가 변할 때만 useEffect 안의 코드를 실행해준다.
- 따라서 위의 코드는 count라는 변수가 변할 때만 useEffect 안의 코드가 실행됨.
- [ ] 안에는 여러 state를 넣을 수 있다.
useEffect(()=>{ 실행할코드 }, [])
- 아무것도 넣지 않는다면 컴포넌트가 mount시 (로드시) 1회 실행하고 영영 실행되지 않는다.
clean up function
useEffect(()=>{
그 다음 실행됨
return ()=>{
여기있는게 먼저실행됨
}
}, [count])
- useEffect 동작하기 전에 특정코드를 실행하고 싶으면 return () => {} 안에 넣을 수 있다.
- 그럼 useEffect 안에 있는 코드를 실행하기 전에 return () => {} 안에 있는 코드를 실행해준다.
- 이것을 clean up function이라고 한다.
- 이걸 쓰는 이유?
- 위에 했던 타이머에서 활용을 해보면 setTimeout() 쓸 때마다 브라우저 안에 타이머가 하나 생긴다.
- 근데 useEffect 안에 썼기 때문에 컴포넌트가 mount 될 때마다 실행이 된다.
- 여차하면 타이머가 100개 1000개 생길수도 있음
- 이러한 버그를 방지하기 위해 useEffect에서 타이머 만들기 전에 기존 타이머를 제거하라는 명령을 내리기 위해 사용될 수 있다.
useEffect(()=>{
let a = setTimeout(()=>{ setAlert(false) }, 2000)
return ()=>{
clearTimeout(a)
}
}, [])
- 이것이 타이머를 제거할 때 사용되는 클린업 함수 (clearTimeout(타이머))
- clean up function에는 타이머제거, socket 연결요청제거, ajax 요청 중단 이러한 코드를 많이 작성
- 컴포넌트 unmount 시에도 clean up function 안에 있던게 1회 실행된다.
정리
useEffect(()=>{ 실행할코드 })
- 재렌더링마다 코드를 실행가능
useEffect(()=>{ 실행할코드 }, [])
- 컴포넌트 mount시 (로드시) 1회만 실행가능
useEffect(()=>{
return ()=>{
실행할코드
}
})
- useEffect 안의 코드 실행 전에 항상 실행
useEffect(()=>{
return ()=>{
실행할코드
}
}, [])
- 컴포넌트 unmount시 1회 실행
useEffect(()=>{
실행할코드
}, [state1])
- state1이 변경될 때만 실행
응용
input 하나 만들고 유저가 숫자 말고 다른 걸 입력하면 "숫자를 입력하세요"라는 안내메시지 출력
function Detail(){
let [num, setNum] = useState('')
useEffect(()=>{
if (isNaN(num) == true){
alert('그러지마세요')
}
}, [num])
return (
<input onChange={ (e) => { setNum(e.target.value) } } />
)
}
- <input>에 입력한 값은 출력해보면 전부 문자 형태로 출력된다.
- 'isNaN()'을 사용하면 isNaN('abc') 이러면 true가 나오고 isNaN('123') 이러면 false가 나오는 걸 활용
'React' 카테고리의 다른 글
탭 UI (0) | 2024.11.28 |
---|---|
ajax - axios (0) | 2024.11.26 |
styled-component (0) | 2024.11.25 |
URL 파라미터 (2) | 2024.11.13 |
navigate, nested routes, outlet (0) | 2024.10.22 |