솔적솔적

React의 Lifecycle, useEffect 사용하기 본문

Front-end/REACT - Basic

React의 Lifecycle, useEffect 사용하기

카드값줘체리 2022. 9. 7. 11:58

| Lifecycle이란

예를들어서 detail페이지있잖아요,

화면에 detail페이지가  보이는 순간 이 때를 페이지에 장착이 된다. 또는 마운트(mount)된다라고도하고,

 

컴포넌트 안에서 state 조작을하면 update되는 과정도 있고, 

 

컴포넌트가 쓸모가 없어지는 경우, 이 경우 컴포넌트 제거되는데 이게 unmount 라고한다.

이런 살아나서 죽는 생물같이 리액트에도 삶의 주기가 있다는 것.

 

mount

update

unmount

이 라이프사이클을 알고 있다면, 중간중간 내가 코드에 간섭을 하여,  특정코드를 실행할 수 있다.

update될 때 특정 코드 실행할 수 있고, unmount될 때 중간에 코드를 넣어 실행할 수 있다는 것이다.

 

그리고 function들 안에서 기본적으로 쓸 수 있는 함수, useEffect가 있는데, 

이 useEffect를 사용해보자. 

여기서 useEffect의 Effect란

프로그래밍할 때쓰는 용어 중에 sideEffect가 있는데, 이게 함수의 핵심기능, 부가기능들을 담당하는 얘들이다.

그거에서 따온 것이라고한다. useEffect에 들어갈 것들은 함수의 핵심기능이 아닌 그 외의 것들이기 때문에 

리액트를 만든 사람이 그렇게 지었다고 한다.

 

그럼 이어서, 

function Detail(props) {

    useEffect(()=>{
     여기에 mount, update시 코드를 넣어 실행시킴 
    });

 

재렌더링을 시켜보자. (update 시켜보자)

function Detail(props) {

    const [count, setCount] = useState(0);

    useEffect(()=>{
      console.log('하이')
    });

    return (
        <div className='flex-box'>
          <h1 className='green'>상세페이지</h1>
          <p>{count}</p>
          <button onClick={()=>{setCount(count + 1)}}>버튼</button>
          
        --  뒤 코드 생략생략 --

그럼, 화면의 F12를 확인하면 누를 때 마다 업데이트되어 '하이' 가 나오는 것을 볼 수 있다.

 

그럼 이걸 왜 쓰느냐?

 

| useEffect을 사용하는 이유 

한마디로 요약한다면 실행시점이 다르다.

랜더링이 다 되고 나서야 실행된다는 것이다( = useEffect안에 있는 코드는 html 렌더링 후에 동작) 

 

만약 반복문을 이 detail 안에서 사용하려한다해보자.

 

자바스트립트는 위에서 부터 차례대로 코드를 읽는데, 그렇게되면

자바스크립트는 html 이 나중에 보여지게된다. 

 

그럼 순서가 반복문 -> html 을 읽게되는데, 

반복문의 실행시간이 1초, 2초걸린다면 그 후에 html이 보이겠지.

근데, 이 반복문을 useErrect안에 넣게되면

좀 더 효율적으로 동작가능하고 유저한테도 더 빠르게 보여줄 수 있다는 것이다.

 

따라서 

서버에서 데이터를 가져오는 작업, 

어려운 연산이나,

타이머를 장착하거나 할 때 useEffect를 사용한다.

 

 

그럼, 간단하게 setTimeout()를 사용하여 3초 뒤에 화면에서 사라지는 할인문구를 만들어보도록하자.

function Detail(props) {

    const [alert, setAlert] = useState(true); //UI 상태저장할 state

    useEffect(()=>{
      const timeAlert = setTimeout(()=>{
        setAlert(false)
      }, 3000);
      return ()=>{clearTimeout(timeAlert)}
    }, [alert]);


    const [inputValue, setInputValue] = useState()

    return (
        <div className='flex-box'>
          <h1 className='green'>상세페이지</h1>
        		
                -- 중간 코드 생략 -- 
        </div>
            
            {
              alert === true ?<Alert/>:null 
            }
          </div>
        </div>
    )
}


function Alert(){
  return (
    <div className='alert2'>
      <p>30초후 구매시 할인 30%</p>
    </div>
  )
}

 

 

근데 이 때 이 뒤에 있는 얘는 뭘까

 

여기는 useEffect의 실행조건을 넣을 수 있는 곳이다.

원래 이걸 쓰지않을 때는 컴포넌트가 로드될 때 monut, update시 실행되는데, 

위처럼 dependency, 변수를 추가하게되면 

변화할 때마다 즉, [ ]안에있는 state가 변할 때만 실행된다는 것이다.

[] 안에 실행 조건을 추가한다면 효율적인 타이머를 만들 수 있다.

 

또한 useEffect에서 쓸 수 있는 추가 문법이 있는데, 그것은 return.

useEffect동작 전에 실행되는 return () =>{ }

 

 

재렌더링이 많은 리액트 특성상, 타이머를 넣을 때 

기존 타이머를 제거한 상태에서 내가 필요한 타이머만 장착하여 실행할 수 있기 때문에 clean up function을 이용한다. 

 

참고할 점은 clean up function은 mount시 실행되지않고 unmount시 실행된다.

 

 

다시 정리한다면

💗 재렌더링마다 코드를 실행하고 싶다? 👉 useEffect(()=>{ })

💗 mount시 1회 코드를 실행하고 싶다? 👉 useEffect(()=>{ }, [] )

💗 unmount시 1회 코드를 싱행하고 싶다? 👉 useEffect(()=>{  return () => { }}, [])