useEffect로 컴포넌트 라이프싸이클 흉내내기

공부는 혼자하는 거·2021년 8월 21일
0

React Tip

목록 보기
16/24

useEffect의 기본 형태

useEffect(()=>{
	console.log("");
})

useEffect는 기본적으로 componentDidMount, componentDidUpdate, componentWillUnmount, getDerivedStateFromProps의 역할을 모두 합니다.

때문에 위 코드는 1) 컴포넌트가 마운트 된 후, 2) 컴포넌트가 업데이트되고 난 후 3) 컴포넌트가 언마운트 되기 전 모두 실행됩니다.

https://killu.tistory.com/44

  • useEffect는 아래와 같이 2가지의 인수를 받습니다. 하나는 useEffect가 실행할 함수이며, 두 번째는 이 함수를 실행시킬 조건입니다.
useEffect(<function>, <array>);
  • useEffect는 함수를 반환할 수 있습니다. 이를  이라고 표현합니다.

    clean-up

useEffect(()=>{
	console.log("");
    return(() => func());
})
  • 이 clean-up함수는 useEffect가 실행될 때마다 실행됩니다.

클래스 컴포넌트 생명주기

component가 mount 시작 되면

  1. constructor가 가장 먼저 실행

  2. getDerivedStateFromProps에서 props와 state를 비교

  3. render component

  4. update DOM

  5. componentDidMount가 실행

component가 update 될 때 (new props or setState)

  1. getDerivedStateFromProps에서 props와 state 비교

  2. shouldComponentUpdate 실행 - new props, state를 확인하고 rerender 할 것인지 결정

  3. rerender

  4. update DOM

  5. componentDidUpdate 실행

component가 unmount 될 때

  1. componentWillUnmount 실행

useEffect로 클래스 컴포넌트 라이프싸이클 흉내내기

ComponentDidMount

useEffect(()=>{
	console.log("componentDidMount");     
},[])
//컴포넌트 마운트시에만 실행됩니다.

ComponentDidUpdate or getDerivedStateFromProps

cosnt { exampleProp } = props;
const [count, setCount] = useState(0);
//일단 마운트 될 때 무조건 실행되고
useEffect(() => {
	console.log("count or exampleProp changed");     
},[count, exampleProp]);
//조건에 특정 state 혹은 props를 전달하면 이 state 혹은 props가 변할 때만 useEffect가 실행됩니다.

componentDidMount


// 클래스의 경우 -> constructor -> render -> ref -> componentDidMount
// (setState/props 바뀔때) -> shouldComponentUpdate(true) -> render -> componentDidUpdate
// 부모가 나를 없앴을 때 -> componentWillUnmount -> 소멸

useEffect(() => {
//보통 ajax
    console.log('componentDidMount에서만 실행');
  }, []);

// 만약 componentDidUpate()에서만 실행하게 하고 싶다 라고 하면
  // 패턴이니까 기억해두기
  const mounted = useRef(false);
  useEffect( () => {
    if(!mounted.current){
      mounted.current = true;
    }else{
      //ajax
    }

  },['바뀌는 값']); //componentDidMount에서는 실행 안함

위 코드를 custom hooks 으로 작성

//오직 state가 변경될 때만 useEffect 실행하도록 customhooks 작성...
export default function useUpdateEffect(fn, dependencies = []) {
  const isInitialMount = useRef(false);

  useEffect(() => {
    if (!isInitialMount.current) {
      isInitialMount.current = true;
    } else {
      return fn();
    }
  }, dependencies);
}

//사용시

useUpdateEffect(() => {
    console.log(loginDone, 'loginError', loginError);

    if (loginDone) {
      alert('로그인 성공'); //매번 랜더링 될 때마다 실행되네.. home애서 실행하도록 해야겠다...
      setLoginVisible(false);
      //console.log('쿠키는?', document.cookie);
    }

    if (loginError) {
      alert('로그인 실패');
      return;
    }
  }, [loginDone, loginError]);
useEffect(() => {
    //console.log('loginLoading: ', loginLoading, 'joinLoaing', joinLoading);
    //console.log('loginDone', loginDone, 'trigger 안 되는디..');
    //console.log('joinDone', joinDone, 'trigger 안 되는디..');
    //왜 여기서 바로 반영이 안 되는 거지...진짜 짜증나네...이유를 모르겠으니까 답답해 뒤지겄네..
    //당연히 랜더링 자체가 되지 않으니 실행이 안 되는 거네... 바보였는가...
    console.log('data', data);

    if (data) {
      console.log('null이 아니라면', data.msg);
    }
  }, [loginLoading, joinLoading, data]);

당연히 랜더링 자체가 되지 않으니 실행이 안 되는 거네... 바보였는가...!!!!!!

https://overreacted.io/ko/a-complete-guide-to-useeffect/

https://ko.reactjs.org/docs/hooks-effect.html

https://daveceddia.com/useeffect-hook-examples/#useeffect-does-not-actively-watch

React useEffect only on Update

https://www.robinwieruch.de/react-useeffect-only-on-update
https://jungpaeng.tistory.com/92
https://stackoverflow.com/questions/55075604/react-hooks-useeffect-only-on-update
https://stackoverflow.com/questions/53179075/with-useeffect-how-can-i-skip-applying-an-effect-upon-the-initial-render

ComponentWillUnmount

useEffect(()=>{
	console.log("");     
    return(() => {//정리 });
})

- ComponentWillUnmonut의 역할은 clean-up 함수를 통해 구현할 수 있습니다.

- 컴포넌트가 Unmount될 때 정리하거나 unscribe 해야할 것이 있다면 useEffect의 return 값으로 전달합니다.
useEffect(() => {  //하나의 예시
    // scroll 이벤트를 만들어줍니다. 스크롤을 움직일때 마다 
    // onScroll 함수가 실행됩니다.
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll); <---- 집중 !!!
  }, []);
  return state;
};

https://velog.io/@jeonghoheo/React-Hooks리액트-훅스의-기본-Part-1-2jjxpaobgg

useeffect에 등록되는 함수에 asyn를 붙이면 안 됨. 반환되는 값은 뒷정리 함수이기 때문

함수 내부에는 가능

loading이라는 상태도 관리하여 api 요청이 대기 중인지 판별, 요청이 대기중일 때 loading 값이 true가 됨

import React, { useEffect, useState } from 'react';

export default function usePromise(promiseCreator, deps) {
  const [loading, setLoaing] = useState(false);
  const [resolved, setResolved] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const process = async () => {
      setLoaing(true);
      try {
        const resolved = await promiseCreator();
        setResolved(resolved);
      } catch (error) {
        setError(error);
      }
      setLoaing(false);
    };
    process();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps);

  return [loading, resolved, error];
}
profile
시간대비효율

0개의 댓글