컴포넌트 페이지에서 2초후에 div박스가 사라지게 해보겠습니다.
let Box = styled.div`
background:yellow;
padding:20px;
`
function Detail(){
let[temp,settemp] = useState(0);
useEffect(()=>{
setTimeout(()=>{
settemp(1);
},2000)
})
return (
{
temp==1 ? null : <Box></Box>
}
)
}
위의 코드를 실행시켜보면 2초후에 박스가 사라집니다.
근데 []를 useEffect에 사용하면 더 좋은 코드가 나옵니다.
useEffcet 실행조건
useEffect()의 둘째 파라미터로 []를 넣을 수 있는데 거기에 변수나 state같은 것들을 넣을 수 있습니다.
그렇게하면 []에 있는 변수나 state가 변할 때만 useEffect 안의 코드를 실행해줍니다.
아래의 코드는 count라는 변수가 변할 때만 useEffect안의 코드가 실행됩니다.( []안에 state여러개 가능)
useEffect(()=>{ 실행할코드 }, [count])
그리고 [ ] 안에 아무것도 넣지 않으면 컴포넌트 mount시(로드시) 1회실행하고 영영 실행해주지 않습니다.
그래서 확인을 해보면 아래의 코드를 실행시켜봅니다.
현재 useEffect는 count에 영향을 받습니다. 그래서 버튼으로 count를 증가시켜보면
function DetailPage(props) {
let[count,setCount] = useState(0);
let[count2, setCount2] = useState(0);
useEffect(()=>{
console.log('useEffect');
}, [count])
let {id} = useParams();
return (
<div className="container">
<button onClick={()=>{setCount(count+1)}}>count</button>
<button onClick={()=>{setCount2(count2+1)}}>count2</button>
...
)
}
count를 두번눌렀을때 안의 코드가 실행됩니다.
count2를 눌렀을때( useEffect에 없는 변수) 실행되지 않습니다.
clean up function
useEffect 동작하기 전에 특정코드를 실행하고 싶으면
return () => {} 안에 넣을 수 있습니다.
useEffect(()=>{
그 다음 실행
return ()=>{
여기있는게 먼저실행
}
}, [count]
저거를 clean up function 이라고 부릅니다. 왜 저런기능이 있냐면
예를들면 setTimeout()을 쓸 때마다 브라우저 안에 타이머가 하나 생깁니다. 근데 useEffect안에
썻기 때문에 컴포넌트가 mount 될 때마다 실행됩니다.
그럼 잘못 코드를 짜면 타이머가 100개 .. 이상 생길 수도 있습니다.
나중에 그런 버그를 방지하고 싶으면 useEffect에서 타이머 만들기 전에 기존 타이머를 싹 제거해야하는데
그럴때 return()=>{} 안에 짜면 됩니다.
타이머를 제거하고 싶으면 clearTimouet(타이머)를 사옹하면됩니다.
그래서 이전에 짯던 코드에서 아래와 같이 사용해주면 기존 타이머를 제거해주는 안전한 코드가 됩니다.
useEffect(()=>{
let a =setTimeout(()=>{
setTemp(1);
},2000)
return ()=>{
clearTimeout(a)
}
}, [])
- clean up function에는 타이머제거, socket 연결요청제거, ajax 요청 중단 이런 코드를 많이 작성
- 컴포넌트 unmount 시에도 clean up function 안에 있던게 1회 실행
정리
useEffect(()=>{ 실행할코드 })
1. 이러면 재랜더링 마다 코드를 실행가능합니다.
useEffect(()=>{ 실행할코드 }, [])
2. 이러면 컴포넌트 mount시(로드시) 1회만 실행가능합니다.
useEffect(()=>{
return ()=>{
실행할코드
}
})
3. 이러면 useEffect안의 코드 실행 전에 항상 실행됩니다.
useEffect(()=>{
return ()=>{
실행할코드
}
}, [])
4. 이러면 컴포넌트 unmount시 1회 실행됩니다.
useEffect(()=>{
실행할코드
}, [state1])
5. 이러면 state1이 변경될 때만 실행됩니다.
추가적으로 input을 하나 만들어서 숫자 말고 다른걸 입력하면 "숫자만입력하세요"라는 안내메시지를 출력해보겠습니다.
useEffect를 이용해보겠습니다.
처음에 당연히 if문을 사용하면 안될 줄 알고 삼항연산자를 이용해서 할라했으나 안되길래 1시간정도 고민하다가 정답을 보니 if문을 return문 밖에서 쓰면 되는 걸 알고 사용했습니다..
( if문을 사용하면 안되는 줄 알았으나 return() 안에서만 사용하지 않으면 되는것이었습니다..)
function DetailPage(){
let[check,setCheck] = useState(false);
useEffect(()=>{
check = isNaN(number);
console.log(check);
if(check==true)
{
alert("문자열만입력");
}
}, [number])
return (
<input onChange={(e)=>{
setNumber(e.target.value);
console.log(number);
}}></input>
)
}
'프론트엔드 > react' 카테고리의 다른 글
React - 리액트에서 탭 UI 만들기 (0) | 2023.08.04 |
---|---|
React - ajax (0) | 2023.08.04 |
React - Lifecycle과 useEffect 1 (0) | 2023.08.01 |
React - styled-components (0) | 2023.08.01 |
React - URL 파라미터, 다른js파일컴포넌트 (0) | 2023.08.01 |