리액트

리액트> Lifecycle과 useEffect 1

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

오늘은 Lifecycle 어쩌구랑 useEffect라는 함수에 대해 알아봅시다. 

어딜 들쳐봐도 다들 어렵게 가르치는 Lifecycle 이라는 개념이 있는데 실은 별거아닙니다.

이걸 배우는 이유는 componentDidMount() 이런 유용한 Lifecycle 함수들을 쓰기 위해서 배우는겁니다.

요즘 사람들은 저렇게 긴 함수 안쓰고 useEffect() 라는 깔끔한 함수를 사용하기 때문에 우리도 그걸 배워봅시다.

 

 

 

 

 

컴포넌트의 인생 

 

여러분이 만들어쓰고있는 컴포넌트는 Lifecycle이라는 개념이 있습니다.

컴포넌트도 인생이 있다는겁니다.

 

 

 

컴포넌트는

1. 생성이 될 수도 있고 (전문용어로 mount)

2. 재렌더링이 될 수도 있고 (전문용어로 update)

3. 삭제가 될 수도 있습니다. (전문용어로 unmount)

 

 

우리 인생 살기도 힘든데 컴포넌트의 인생 알아서 뭐합니까

뭔가를 배우면 어디다 쓸지 생각해보아야 합니다. 그래야 나중에 활용하겠죠?

컴포넌트의 인생을 배우는 이유는 컴포넌트 인생 중간중간에 간섭할 수 있기 때문입니다.

간섭이 뭐냐면 그냥 코드실행인데 

컴포넌트가 장착이 될 때 특정 코드를 실행할 수도 있고 

컴포넌트가 업데이트될 때 특정 코드를 실행할 수도 있다는 겁니다.

그럼 재밌는 기능들 개발가능 

 

 

 

 

 

 

인생에 간섭하는 방법 

 

"Detail 컴포넌트 등장 전에 이것좀 해줘"

"Detail 컴포넌트 사라지기 전에 이것좀 해줘"

"Detail 컴포넌트 업데이트 되고나서 이것좀 해줘"

이렇게 코드좀 실행해달라고 간섭할 수 있는데

간섭은 갈고리를 달아서 합니다. 

 

 

 

갈고리를 달아서 코드를 넣어주면 됩니다.

그럼 진짜 페이지 장착시, 업데이트시, 제거시 코드실행가능 

갈고리는 영어로 hook이라고 합니다. 

그래서 저걸 Lifecycle hook 이라고 부릅니다. 

 

 

 

 

 

 

 

옛날 React에서 Lifecycle hook 쓰는 법

 

 

class Detail2 extends React.Component {
  componentDidMount(){
    //Detail2 컴포넌트가 로드되고나서 실행할 코드
  }
  componentDidUpdate(){
    //Detail2 컴포넌트가 업데이트 되고나서 실행할 코드
  }
  componentWillUnmount(){
    //Detail2 컴포넌트가 삭제되기전에 실행할 코드
  }
}

예전엔 class 문법으로 컴포넌트를 만들었습니다.

그 경우엔 안에 함수명을 저렇게 써주면 각각 특정 Lifecycle에서 코드를 실행할 수 있었습니다.

 

 

 

 

 

 

요즘 React에서 Lifecycle hook 쓰는 법

 

 

import {useState, useEffect} from 'react';

function Detail(){

  useEffect(()=>{
    //여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
    console.log('안녕')
  });
  
  return (생략)
}

상단에서 useEffect import해오고 

콜백함수 추가해서 안에 코드 적으면 이제 그 코드는 컴포넌트가 mount & update시 실행됩니다.

그래서 이게 Lifecycle hook 입니다. 

진짜 Detail 페이지 로드시 콘솔창에 '안녕' 출력되나 확인해봅시다. 

 

 

 

 

import {useState, useEffect} from 'react';

function Detail(){

  useEffect(()=>{
    //여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
    console.log('안녕')
  });

  let [count, setCount] = useState(0)
  
  return (
    <button onClick={()=>{ setCount(count+1) }}>버튼</button>
  )
}

재렌더링시에도 진짜 '안녕' 출력되나 테스트해보려고 

버튼누르면 재렌더링되게 코드짜봤습니다.

버튼눌러서 실험해봅시다. 

 

 

 

 

Q. 왜 저는 '안녕' 2번 출력됨?

index.js에 <React.StrictMode>라는 태그가 있으면 2번 출력해줍니다.

디버깅용으로 편하라고 2번 출력해주는데 싫으면 저 태그를 제거하거나 그럽시다. 

 

 

 

 

 

 

 

근데 useEffect 밖에 적어도 똑같은데요

 

들킴

실은 useEffect 바깥에 적어도 똑같이 컴포넌트 mount & update시 실행됩니다. 

컴포넌트가 mount & update시 function 안에 있는 코드도 다시 읽고 지나가서 그렇습니다. 

그럼 대체 useEffect 왜 만들어놓은 것이죠 

 

그래서 문법 배우는게 중요한게 아니라 이걸 배웠으면

어떤 상황에서 언제 사용할지도 함께 배워야합니다. 

그래야 나중에 "여기서 useEffect 써도 되나요" 이런 초보질문 안함

 

useEffect 안에 적은 코드는 html 렌더링 이후에 동작합니다.

그럼 이제 useEffect가 뭔가 유용할 것 같지 않습니까 

예를 들어서 굉장히 시간이 오래걸리는 쓸데없는 코드가 필요하다고 가정해봅시다.

 

 

 

 

function Detail(){

  (반복문 10억번 돌리는 코드)
  return (생략)
}

▲ 여기에 대충 적으면 반복문 돌리고 나서 하단의 html 보여줌

 

 

function Detail(){

  useEffect(()=>{
    (반복문 10억번 돌리는 코드)
  });
  
  return (생략)
}

▲ useEffect 안에 적으면 html 보여주고 나서 반복문 돌림 

 

이런 식으로 코드의 실행 시점을 조절할 수 있기 때문에

조금이라도 html 렌더링이 빠른 사이트를 원하면

쓸데없는 것들은 useEffect 안에 넣어보길 바랍니다. 

 

 

그래서 이걸 알면 리액트만든 놈이 이 함수를 useEffect라고 작명한 이유도 알 수 있는데 

함수안에 이것저것 코드짤 때 

함수의 핵심기능 외에 쓸데없는 기능들을 프로그래밍 용어로 side effect라고 부릅니다.

 

그래서 useEffect도 거기서 따온건데

컴포넌트의 핵심 기능은 html 렌더링이라 

그거 외의 쓸데없는 기능들은 useEffect 안에 적으라는 소리입니다. 

오래걸리는 반복연산, 서버에서 데이터가져오는 작업, 타이머다는거 

이런건 useEffect 안에 많이 적습니다.

 

 

 

 

 

 

오늘의 숙제 :

Detail 페이지 안에 노란 박스 하나 만들고

Detail 페이지 방문 후 2초 후에 박스가 사라지게 해보십시오.

 

(팁) 동적인 UI 어떻게 만든다고 했습니까 

 

 

그전에 알아야할 내용 setTimeout

 

자바스크립트로 X초 후에 코드를 실행하고 싶으면 setTimeout이라는 함수를 사용합니다.

 

setTimeout( ()=>{  1초 후 실행할 코드 }, 1000);

사용법은 이렇습니다.

1000이라고 숫자적은 곳에 ms 단위로 시간을 적어주시면 됩니다.

1000이라고 적으면 1초겠죠? 1초 후에 내부 코드를 실행해줍니다.