Lifecycle

컴포넌트도 사람처럼 죽고 산다.

  • 페이지에 장착 (mount)
  • 업데이트 됨 (update)
  • 필요없으면 제거 됨 (unmount)

이런식이야

중간중간 간섭 가능하다.

간섭이란? 그냥 코드 실행이다.

컴포넌트 업데이트, 삭제 될 때 재밌는 기능들 구현할 수 있다.

어떻게 간섭할 수 있는가 거기에 갈고리를 달아서 코드를 달아둠.

그러면, 그 때 실행됨.

갈고리를 달아보자

// 옛날에는 
class Detail2 extends React.Component {
  componentDidMount() {
    // 컴포넌트 마운트 될 때
  }
  componentDidUpdate() {
    // 컴포넌트 업데이트 될 때
  }
  componentWillUnmount() {
    // 컴포넌트 제거 될 때
  }
}

// 요즘에는
function Detail(props) {
  // 이렇게 쓰면, 
  // 장착 될 때 & update 될 때 
  useEffect(()=> {
    // 이렇게 하면 두번 실행 됨
    // * 리액트는 디버그를 위해서 두번정도 실행된다고 보면 됨
    console.log('안녕');
  })
}

useEffect를 언제쓸지가 중요하다.

실행시점이 약간 다르다.

useEffect는
html이 렌더링 후에 동작한다.

원래 동작순서가

js 작업 => html

이렇게 되어있다.

근데 js 코드를 useEffect 안에 넣어두면 html을 먼저 보여주고, 그 다음 어려운 작업을 동작시킨다.

  • 어려운 연산,
  • 서버에서 데이터 가져오는 작업
  • 타이머 장착하는 것

왜 이름이 Effect냐?

Side Effect : 함수의 핵심기능과 상관없는 부가기능

그거에서 따온 함수명이란다.

Side Effect 코드 보관소라고 보면 됨

그래서 2초 후에 div태그 숨기는 기능이 담긴 코드는 아래와 같다.

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import styled from "styled-components";

function Detail(props) {
  let { id } = useParams(); // 현재 url의 parameter 정보가 남음
  let [alertshow, setShow] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      console.log('안녕');
      setShow(false);
    }, 2000);
  }, []);


  return (
    <div className="container">
      {
        alertshow == true ? <div className="alert alert-warning">2초 이내 구매 시 할인</div> : null
      }
      <div className="row">
        <div className="col-md-6">
          <img
            src={`https://codingapple1.github.io/shop/shoes${+id + 1}.jpg`}
            width="100%"
          />
        </div>
        <div className="col-md-6">
          <h4 className="pt-5">{props.shoes[id].title}</h4>
          <p>{props.shoes[id].content}</p>
          <p>{props.shoes[id].price}</p>
          <button className="btn btn-danger">주문하기</button>
        </div>
      </div>
    </div>
    
  );
  
}


export default Detail;

useEffect 조건을 넣을 수 있음

useEffect(() => {
    setTimeout(() => {
      console.log('안녕');
      setShow(false);
    }, 2000);
  }, [count]);

위에서

  1. 최초실행(mount 시) 그 이후
  2. count값이 변경될 때 감지하여 실행한다.

아무 값도 안넣으면 ([] 만 있으면) 반응하지 않는다.

※ return을 넣을 수 있음

return을 넣으면 useEffect 직전에 실행시켜 clean 시켜준다.

useEffect(() => {
    let timer = setTimeout(() => {
      setShow(false);
    }, 2000);

    return () => {
      clearTimeout(timer);
    }
  }, [count]);

위와 같이 타이머 삭제

혹은 서버로 요청 보낼 때,

useEffect(() => {
    //요청보내는 코드

    return () => {
      //보내고 있는 요청 삭제해주세요
    }
  }, [count]);

clean up function이라고 하는데

이는 mount 될 땐 실행 안되고 unmount 될 때는 실행 된다.

정리

useEffect(() => {}) // 기본형
useEffect(() => {}, []) // 조건형
useEffect(() => { return }) // cleanup