[TIL] React 중급: 함수형 컴포넌트의 라이프-사이클 구현

minami·2021년 7월 6일
0

React

목록 보기
12/12

7. Function Component: Life-cycle 구현

7-1. useEffect

함수형 컴포넌트에서 클래스형 컴포넌트의 componentDidMount, comeponentDidUpdate와 같은 역할. 사용하려면 import를 해야 한다.

  • useEffect의 effect는 side effect라는 뜻이다.
  • Main effect는 return() 안에 작성한 화면 렌더링이며, side effect(useEffect)는 이미 렌더링된 후에 값을 변경하는 것이다.
  • useEffect는 한 번에 여러 개 설치가 가능하다.

7-2. 클래스형 컴포넌트와 함수형 컴포넌트의 라이프 사이클 비교

  • 클래스형 컴포넌트의 componenetDidMount와 함수형 컴포넌트의 useEffect

  • 함수형 컴포넌트의 useEffect와 render 순서

  • 함수형 컴포넌트와 클래스형 컴포넌트의 라이프 사이클

  • 함수형 컴포넌트 코드
var funcStyle = 'color:blue';
var funcId = 0;
function FuncComp(props) {
  // React의 useState에서 state의 초기값(props.initNumber)을 인자로 넣어주면
  var numberState = useState(props.initNumber);
  // useState() 배열의 0번째 값에 현재의 state(initNumber)값이 들어간다.
  var number = numberState[0];
  // class component의 setState처럼 상태를 바꾸려면 배열의 1번째 데이터를 바꾼다.
  var setNumber = numberState[1];

  // var dateState = useState((new Date()).toString());
  // var _date = dateState[0];
  // var setDate = dateState[1];
  // 바로 위 3줄로 나눠서 쓴 것과 똑같이 동작하는 축약형 코드
  var [_date, setDate] = useState((new Date()).toString());

  // 함수형 컴포넌트에서 useEffect는 클래스형 컴포넌트의 componentDidMount, componentDidUpdate와 같은 역할
  // useEffect의 effect는 side effect
  // Main effect는 return() 안에 작성한 화면 렌더링
  // side effect(useEffect)는 이미 렌더링된 후에 값을 변경하는 것
  // useEffect는 여러 개 설치 가능
  useEffect(function() {
    console.log('%cfunc => useEffect (componentDidMount & componentDidUpdate) A' + (++funcId), funcStyle);
    document.title = number + ' : ' + _date;
  });
  useEffect(function() {
    console.log('%cfunc => useEffect (componentDidMount & componentDidUpdate) B' + (++funcId), funcStyle);
    document.title = number + ' : ' + _date;
  });

  // useState()를 쓰면 무조건 2개의 값으로 이루어진 배열이 리턴됨
  // console.log('numberState', numberState);
  console.log('%cfunc => render' + (++funcId), funcStyle);
  return (
    <div className="container">
      <h2>Function style component</h2>
      <p>Number : {number}</p>
      <p>Date : {_date}</p>
      <input type="button" value="random" onClick={
        function() {
          setNumber(Math.random());
        }
      }></input>
      <input type="button" value="date" onClick={
        function() {
          setDate((new Date()).toString());
        }
      }></input>
    </div>
  );
}

7-3. clean-up

useEffect가 한번 실행된 후 다시 실행될 때 이전에 실행했던 값을 정리해주는 것

  • useEffect()에서 파라미터로 넣은 함수의 return값이다.
  • 클래스형 컴포넌트에서는 componentDidMount에서 어떤 설정을 한 뒤 componentWillUnmount에서 이를 정리(clean-up)하는데, 이와 같이 함수형 컴포넌트에서는 어떤 effect가 실행되고 다음 effect가 실행되기 직전에 정리(clean-up)를 해준다.
  • 함수형 컴포넌트에서 clean-up이 실행될 때의 라이프 사이클
    • renderuseEffect 사용 1 ➡ re-renderclean-upuseEffect 사용 2

  • 함수형 컴포넌트 코드
var funcStyle = 'color:blue';
var funcId = 0;
function FuncComp(props) {
  // React의 useState에서 state의 초기값(props.initNumber)을 인자로 넣어주면
  var numberState = useState(props.initNumber);
  // useState() 배열의 0번째 값에 현재의 state(initNumber)값이 들어간다.
  var number = numberState[0];
  // class component의 setState처럼 상태를 바꾸려면 배열의 1번째 데이터를 바꾼다.
  var setNumber = numberState[1];

  // var dateState = useState((new Date()).toString());
  // var _date = dateState[0];
  // var setDate = dateState[1];
  // 바로 위 3줄로 나눠서 쓴 것과 똑같이 동작하는 축약형 코드
  var [_date, setDate] = useState((new Date()).toString());

  // 함수형 컴포넌트에서 useEffect는 클래스형 컴포넌트의 componentDidMount, componentDidUpdate와 같은 역할
  // useEffect의 effect는 side effect
  // Main effect는 return() 안에 작성한 화면 렌더링
  // side effect(useEffect)는 이미 렌더링된 후에 값을 변경하는 것
  // useEffect는 여러 개 설치 가능
  useEffect(function() {
    console.log('%cfunc => useEffect (componentDidMount & componentDidUpdate) A' + (++funcId), funcStyle);
    document.title = number + ' : ' + _date;
    // useEffect가 한번 실행된 후 다시 실행될 때 이전에 실행했던 값을 정리해주는 것이 clean up
    // 예를 들면 입장할 때 구독하고 퇴장할 때 구독취소를 하는 것
    return function() {
      console.log('%cfunc => useEffect return (componentDidMount & componentDidUpdate) B' + (++funcId), funcStyle);
    }
  });
  // useState()를 쓰면 무조건 2개의 값으로 이루어진 배열이 리턴됨
  // console.log('numberState', numberState);
  console.log('%cfunc => render' + (++funcId), funcStyle);
  return (
    <div className="container">
      <h2>Function style component</h2>
      <p>Number : {number}</p>
      <p>Date : {_date}</p>
      <input type="button" value="random" onClick={
        function() {
          setNumber(Math.random());
        }
      }></input>
      <input type="button" value="date" onClick={
        function() {
          setDate((new Date()).toString());
        }
      }></input>
    </div>
  );
}

7-4. Skipping Effects

변경된 propsstate값이 있을 때만 변경된 값으로 effect를 실행해서 성능을 최적화할 수 있다.

  • 클래스형 컴포넌트가 componentDidUpdate에서 prevPropsprevState와 현재 값을 비교하여 현재 값이 바뀌었을 때만 업데이트를 하여 리렌더링하는 것처럼 함수형 컴포넌트에서도 effect의 실행 여부를 판단해서 성능을 최적화할 수 있다.
  • useEffect()에 이전 값과 현재 값을 비교할 인자를 하나 더 넣어주면 된다.
  • number_date를 각각 useEffect()를 사용해서 업데이트할 때 라이프 사이클

  • useEffect()clean-up을 적용했을 때 라이프 사이클

  • useEffect (componentDidMount)를 적용했을 때 라이프 사이클
    • useEffect를 최초에 한 번만 실행해서 componentDidMount와 같은 역할을 하게 할 때는 인자로 빈 배열을 넣어준다.
    • effectclean-up(unmount)되는 때는 부모 컴포넌트에서 이 함수형 컴포넌트를 삭제하게 될 때이다.

  • 함수형 컴포넌트 코드
var funcStyle = 'color:blue';
var funcId = 0;
function FuncComp(props) {
  // React의 useState에서 state의 초기값(props.initNumber)을 인자로 넣어주면
  var numberState = useState(props.initNumber);
  // useState() 배열의 0번째 값에 현재의 state(initNumber)값이 들어간다.
  var number = numberState[0];
  // class component의 setState처럼 상태를 바꾸려면 배열의 1번째 데이터를 바꾼다.
  var setNumber = numberState[1];

  // var dateState = useState((new Date()).toString());
  // var _date = dateState[0];
  // var setDate = dateState[1];
  // 바로 위 3줄로 나눠서 쓴 것과 똑같이 동작하는 축약형 코드
  var [_date, setDate] = useState((new Date()).toString());

  // 함수형 컴포넌트에서 useEffect는 클래스형 컴포넌트의 componentDidMount, componentDidUpdate와 같은 역할
  // useEffect의 effect는 side effect
  // Main effect는 return() 안에 작성한 화면 렌더링
  // side effect(useEffect)는 이미 렌더링된 후에 값을 변경하는 것
  // useEffect는 여러 개 설치 가능
  useEffect(function() {
    console.log('%cfunc => useEffect (componentDidMount) A' + (++funcId), funcStyle);
    document.title = number;
    // useEffect가 한번 실행된 후 다시 실행될 때 이전에 실행했던 값을 정리해주는 것이 clean up
    // 예를 들면 입장할 때 구독하고 퇴장할 때 구독취소를 하는 것
    // 이 effect는 부모 컴포넌트에서 이 함수 컴포넌트를 삭제하는 경우에 clean-up(unmount)을 하게 된다.
    return function() {
      console.log('%cfunc => useEffect return (componentWillUnmount) B' + (++funcId), funcStyle);
    }
  // 빈 배열을 넣으면 처음 한 번만 실행되고 그 후로는 실행되지 않는다.(componentDidMount만 하도록)
  }, []);

  useEffect(function() {
    console.log('%cfunc => useEffect number (componentDidMount & componentDidUpdate) A' + (++funcId), funcStyle);
    document.title = number;
    // useEffect가 한번 실행된 후 다시 실행될 때 이전에 실행했던 값을 정리해주는 것이 clean up
    // 예를 들면 입장할 때 구독하고 퇴장할 때 구독취소를 하는 것
    return function() {
      console.log('%cfunc => useEffect number return (componentDidMount & componentDidUpdate) B' + (++funcId), funcStyle);
    }
    // number만 변경된 것을 감지
  }, [number]);

  useEffect(function() {
    console.log('%cfunc => useEffect _date (componentDidMount & componentDidUpdate) A' + (++funcId), funcStyle);
    document.title = _date;
    // useEffect가 한번 실행된 후 다시 실행될 때 이전에 실행했던 값을 정리해주는 것이 clean up
    // 예를 들면 입장할 때 구독하고 퇴장할 때 구독취소를 하는 것
    return function() {
      console.log('%cfunc => useEffect _date return (componentDidMount & componentDidUpdate) B' + (++funcId), funcStyle);
    }
    // _date만 변경된 것을 감지
  }, [_date]);

  // useState()를 쓰면 무조건 2개의 값으로 이루어진 배열이 리턴됨
  // console.log('numberState', numberState);
  console.log('%cfunc => render' + (++funcId), funcStyle);
  return (
    <div className="container">
      <h2>Function style component</h2>
      <p>Number : {number}</p>
      <p>Date : {_date}</p>
      <input type="button" value="random" onClick={
        function() {
          setNumber(Math.random());
        }
      }></input>
      <input type="button" value="date" onClick={
        function() {
          setDate((new Date()).toString());
        }
      }></input>
    </div>
  );
}
profile
함께 나아가는 개발자💪

0개의 댓글