[React] 컴포넌트 렌더링 이후 effect 수행 - useEffect

Swimme·2021년 1월 27일
4

React

목록 보기
5/6

useEffect Hook

1. runs after every re-render by default 
2. second parameter : dependency list
3. cleanup function

1. 렌더링 후의 동작

  • 컴포넌트가 렌더링 이후에 어떤 일을 수행해야하는 지를 정의
    • 리액트는 브라우저가 다 그려질 때까지 useEffect의 실행을 지연한다.

componentDidMount와 componentDidUpdate, componentWillUnmount가 합쳐진 것으로 생각해도 좋습니다. 하지만, componentDidMount 혹은 componentDidUpdate와는 달리 useEffect에서 사용되는 effect는 브라우저가 화면을 업데이트하는 것을 차단하지 않습니다. = 화면이 그려진 후 실행

  • 렌더링 후의 부가적인 effect
    • side effect : any work outside of the component
    • 외부 데이터 가져오기, 수동으로 리액트 컴포넌트 DOM 수정 등
  • effect를 발생하는 콜백함수와, dependency 배열을 인자로 받는다.
  useEffect( ()=>{} );
  useEffect( ()=>{}, [...]);
  // dependency list는 안써도 무관 = 이 경우 디폴트로 리렌더링마다 effect수행
  • 콜백 effect 함수 자체를 async로 작성할 수 없다 (promise 반환x). 함수 내에서는 사용 가능.
  • useEffect를 컴포넌트 안에서 호출하는 이유
    : 컴포넌트 내부에 둠으로써 effect를 통해 state 변수(또는 prop)에 접근 가능하게 함

2. Dependency Array 인자

  • 의존성 배열 인자에는 effect 함수가 의존하는 변수를 배열로 작성한다.
    • 해당 변수가 업데이트 될 때 effect 실행
  • 작성법에 따라 성능 최적화와 관련이 있다.
  1. 작성하지 않으면, default로 컴포넌트가 re-render될때마다 effect를 수행한다.
  2. 변수가 담긴 배열을 작성하면, 해당 배열의 값들이 변할 때만 effect가 수행된다.
  3. 빈 배열을 작성하면, 처음 렌더링 후에만 effect가 수행된다.
    - prop이나 state에 의존하지 않으므로 재실행되어야 할 필요가 없음을 명시하는 것
 // 모든 리렌더링마다 로그가 찍힘
  useEffect(() => {
    console.log("call useEffect after every re-render");
  }); 

 // value 변수 값이 변할 때만 로그가 찍힘
  useEffect(() => {
    console.log("call useEffect when value changes");
  }, [value]);

 // 첫 렌더링 후에만 로그가 찍힘.
  useEffect(() => {
    console.log("call useEffect only after initial render");
  }, []); 

3. Clean-up function

  • useEffect의 return 값으로 clean up 함수 (기존의 effect를 해지) 작성
  • 메모리 누수가 발생하지 않도록 하기 위함
  • 일반적으로 clean up이 필요하지 않는 effect (네트워크 리퀘스트, DOM 수동 조작, 로깅 등)은 return 값을 명시하지 않음
  • 정리(clean-up)가 필요한 Effects
    • 이벤트 리스너가 계속 추가되는 경우
    • 외부 데이터를 fetch하는 경우
      : 빈 배열을 인자로 넣음으로써 해결할 수도있지만, 의존성이 있는 경우 사용할 수 없음
  • 빈 배열로도 메모리 누수가 해결되지 않는 경우
    • 예시) toggle 기능으로 컴포넌트가 계속 새로 렌더링 되는 경우, 불필요한 이벤트 리스너가 계속 생성될 수 있다. clean up 함수를 반환하여 이전 effect를 정리하도록 하게 해야 한다.
    useEffect(() => {
      window.addEventListener("resize", checkSize);

      return () => {
        window.removeEventListener("resize", checkSize); //다음 useEffect 호출시 실행됨
      };
    }, []);
  • effect를 정리(clean-up)하는 시점
    • 리액트는 컴포넌트가 마운트(실제 DOM삽입) 해제되는 때에 정리 함수를 실행한다.
    • 즉, 다음 차례의 effect를 실행하기 전에 이전의 렌더링에서 파생된 effect를 정리한다.

그 외

  • useEffect는 여러 번 사용가능하기 때문에 관련 로직끼리 묶을 수 있음 (Hook의 동기)
  • 여러 state가 있을때 각 state에 따라 컴포넌트의 일부가 렌더링되게 할 수 있음
profile
Life is Egg..🥚🐣🌟

1개의 댓글

comment-user-thumbnail
2021년 6월 9일

어우 뭔가 useEffect useState에 대해 깔끔하게 정리 해주는글이 없엇는데 겨우 찾앗네요 ㅠㅠ
좋은정보 감사합니다

답글 달기