리액트

리액트> Lifecycle과 useEffect 2

연습노트 2024. 7. 18. 19:03

Detail 페이지 후 2초 후에 박스가 사라지게 해보라고 했습니다. 

동적인 UI 같은거라 그런거 만들 땐 

1. UI 상태를 저장할 state 만들고

2. state에 따라서 UI가 어떻게 보일지 작성하라고 했으니 그거부터 해봅시다. 

 

function Detail(){

  let [alert, setAlert] = useState(true)

  return (
  {
    alert == true
    ? <div className="alert alert-warning">
        2초이내 구매시 할인
      </div>
    : null
  }
  )
}

그랬습니다.

이제 alert라는 state를 true로 바꾸면 노란박스가 보이고

false로 바꾸면 안보임 

 

그럼 이제 Detail 페이지 접속 후 2초 후에 저걸 안보이게 처리하려면 

useEffect와 setTimeout 이런거 쓰면 될듯요 

 

 

function Detail(){

  let [alert, setAlert] = useState(true)
  useEffect(()=>{
    setTimeout(()=>{ setAlert(false) }, 2000)
  }, [])

  return (
  {
    alert == true
    ? <div className="alert alert-warning">
        2초이내 구매시 할인
      </div>
    : null
  }
  )
}

이랬더니 2초 후에 잘 동작하는군요. 

근데 [ ] 이거가 갑자기 어디서 나온건지 알아봅시다. 

 

 

 

 

 

useEffect에 넣을 수 있는 실행조건 

 

useEffect(()=>{ 실행할코드 }, [count])

useEffect()의 둘째 파라미터로 [ ] 를 넣을 수 있는데

거기에 변수나 state같은 것들을 넣을 수 있습니다.

그렇게 하면 [ ]에 있는 변수나 state 가 변할 때만 useEffect 안의 코드를 실행해줍니다.

그래서 위의 코드는 count라는 변수가 변할 때만 useEffect 안의 코드가 실행되겠군요. 

(참고) [ ] 안에 state 여러개 넣을 수 있음

 

 

useEffect(()=>{ 실행할코드 }, [])

아무것도 안넣으면 컴포넌트 mount시 (로드시) 1회 실행하고 영영 실행해주지 않습니다.

그래서 저번시간 숙제에도 [ ] 이걸 넣어봤습니다. 

 

 

 

 

 

clean up function

 

useEffect 동작하기 전에 특정코드를 실행하고 싶으면

return ()=>{} 안에 넣을 수 있습니다. 

 

 

 

useEffect(()=>{ 
  그 다음 실행됨 
  return ()=>{
    여기있는게 먼저실행됨
  }
}, [count])

그럼 useEffect 안에 있는 코드를 실행하기 전에

return ()=>{ } 안에 있는 코드를 실행해줍니다. 

참고로 저걸 clean up function 이라고 부릅니다. 

왜 저딴 쓸데없는 기능이 있냐고요?

 

 

 

 

 

여러분 복잡하고 어려운 숙제할 때 

책상을 싹 치우고 하면 잘되는 것 처럼 

useEffect 안에 있는 코드를 실행할 때도

싹 치우고 깔끔한 마음으로 실행하는게 좋을 때가 있습니다. 

 

예를 들면 숙제로 했던 setTimeout 타이머인데

setTimeout() 쓸 때마다 브라우저 안에 타이머가 하나 생깁니다.

근데 useEffect 안에 썼기 때문에 컴포넌트가 mount 될 때 마다 실행됩니다. 

그럼 잘못 코드를 짜면 타이머가 100개 1000개 생길 수도 있겠군요.

 

나중에 그런 버그를 방지하고 싶으면useEffect에서 타이머 만들기 전에 기존 타이머를 싹 제거하라고 코드를 짜면 되는데

그런거 짤 때 return ()=>{} 안에 짜면 됩니다. 

 

 

useEffect(()=>{ 
  let a = setTimeout(()=>{ setAlert(false) }, 2000)
  return ()=>{
    clearTimeout(a)
  }
}, [])

타이머 제거하고 싶으면 clearTimeout(타이머)

이렇게 코드짜면 됩니다. 

그래서 숙제를 이렇게 하면 좀 더 안전한 코드가 되겠군요.

타이머 장착하기 전에 기존 타이머가 있으면 제거를 해줄듯요 

 

 

 

(참고1) clean up function에는 타이머제거, socket 연결요청제거, ajax요청 중단 이런 코드를 많이 작성합니다.

(참고2) 컴포넌트 unmount 시에도 clean up function 안에 있던게 1회 실행됩니다.

 

 

 

 

 

 

 

 

빡통식 정리시간 

 

저런 코드가 언제 실행되는지만 잘 알아두면 알아서 개발가능한데

원리이해가 싫다면 사용법만 정리해둡시다. 

 

 

useEffect(()=>{ 실행할코드 })

1. 이러면 재렌더링마다 코드를 실행가능합니다.

 

 

useEffect(()=>{ 실행할코드 }, [])

2. 이러면 컴포넌트 mount시 (로드시) 1회만 실행가능합니다.

 

 

useEffect(()=>{ 
  return ()=>{
    실행할코드
  }
})

3. 이러면 useEffect 안의 코드 실행 전에 항상 실행됩니다. 

 

 

useEffect(()=>{ 
  return ()=>{
    실행할코드
  }
}, [])

4. 이러면 컴포넌트 unmount시 1회 실행됩니다.

 

 

useEffect(()=>{ 
  실행할코드
}, [state1])

5. 이러면 state1이 변경될 때만 실행됩니다.