useEffect

pbs1014·2022년 4월 9일
0

useEffect

useEffect 는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정 할 수 있는 Hooks 이다. 클래스형 컴포넌트의 componentDidMount 와 componentDidUpdate 를 합친 형태라 생각하면 이해가 쉽다.

아래 코드는 버튼을 올리면 카운트를 올리는 간단한 코드이다 한번 살펴보자

import { useRef, useState, useEffect } from "react";
import { useRouter } from "next/router";


export default function CounterPage() {
  const router = useRouter();

  const inputRef = useRef<HTMLInputElement>(null);
  const [count, setCount] = useState(99);

  // 1번 DidMount
  // useEffect(() => {
  //   console.log("마운트됨");
  //   inputRef.current?.focus();
  // }, []);

  // componentDidUpdate() {
  //   console.log("수정되고 다시그려짐!!!");
  // }
  // 위의 useEffect와 대괄호 차이

  // 2번 DidUpdate
  useEffect(() => {
    console.log("수정되고 다시그려짐!!!");
  }, [count]); // count 변경시 실행을 의미
  // [count, writer, title]); 이 될경우 셋중 하나만 바뀌어도 실행이됨

  // componentWillUnmount() {
  //   console.log("컴포넌트 사라짐!!!");
  //   // 채팅방 나가기
  //   // api 요청!!!
  // }

  // 3번 Willunmount
  // useEffect(() => {
  //   return () => {
  //     console.log("컴포넌트 사라짐!!!");
  //   };
  // }, []);

  // 4번 DidMount와 willUnmount를 합치기!!
  useEffect(() => {
    console.log("마운트됨");
    inputRef.current?.focus();

    return () => {
      console.log("컴포넌트 사라짐!!!");
    };
  }, []);
  // [] 는 의존성 배열(Dependency Array)라 하며 함수 실행여부를 의존한다. 비었을 경우 한번 실행한 후 끝

  // 5번 useEffect의 잘못된 사용 예시() 1.추가 랜더링, 2.무한루프
  // useEffect안에서 setState를 사용시 재 랜더링이 발생한다.
  // 어쩔수 없을 경우가 아니라면 가능하면 빼주는게 좋다.

  // 1. 추가랜더링
  // useEffect(() => {
  //   setCount(10);
  // }, []);

  // 2. 무한루프
  // useEffect(() => {
  //   setCount((prev) => prev + 1);
  // }, [count]);

  const onClickCounter = () => {
    setCount((prev) => prev + 1);
  };

  const onClickMove = () => {
    router.push("/");
  };

  return (
    // div의 범위가 현재 컴포넌트
    <div>
      {/* 객체 안의 정보를 가져오기에 {} 를 한다. */}
      <input type="text" ref={inputRef} />
      <div>현재카운트{count}</div>
      <button onClick={onClickCounter}>카운트 올리기!!!</button>
      <button onClick={onClickMove}>나가기!!!</button>
    </div>
  );
}

우선 const [count, setCount] = useState(99);를 통해 state를 하나 만들어 초기값은 숫자로 주었다.

1번

1번 DidMount
  useEffect(() => {
  console.log("마운트됨");
  inputRef.current?.focus();
  }, []);

위 부분은 클래스형 컴포넌트의 DidMount라 보면된다.
화면이 랜더링됨과 동시에 작동하는 부분이다.

그런데 코드의 마지막 부분을 보면 [ ]가 들어있다.
[] 는 의존성 배열(Dependency Array)라 하며 함수 실행여부를 의존한다.
위 코드 처럼 [ ] 안쪽이 비었을 경우 한번 실행한 후 다시 다시 실행되지 않으며,

위 코드는 결국 화면 랜더링 최초1회한정으로 적용이되는 함수라는 소리이다.

2번

  //2번 DidUpdate
  useEffect(() => {
    console.log("수정되고 다시그려짐!!!");
  }, [count]); // count 변경시 실행을 의미
  // [count, writer, title]); 이 될경우 셋중 하나만 바뀌어도 실행이됨

위 부분은 클래스형 컴포넌트의 componentDidUpdate() 라고 생각하면 된다.
Update라는 의미 그대로 변경시 효과를 나타내며 위에서 설명한 의존성배열 안에
State값인 count를 넣어서 countsetState에 의해 변경 될 때 마다 콘솔에 로그를 띄워준다.

3번

 3번 Willunmount
   useEffect(() => {
     return () => {
       console.log("컴포넌트 사라짐!!!");
     };
   }, []);

이 부분은 willunmount에 속한다. 마운트가 해제되는 시점으로
의존성 배열 부분이 비어있으므로 한번 만실행되며

return안에 console.log가 들어가 있는데 이는 특정한 이벤트가 발동 될 경우 이벤트가 일어난단 소리이다.

위의 경우에는 마운트가 종료되는 시점에 콘솔이 나올것이다.

4번

 4번 DidMount와 willUnmount를 합치기!!
  useEffect(() => {
    console.log("마운트됨");
    inputRef.current?.focus();

    return () => {
      console.log("컴포넌트 사라짐!!!");
    };
  }, []);

이부분은 DidMountwillUnmount가 합쳐진 부분이라 생각하면 된다.

최초1회 한해서 console.log("마운트됨");가 실행되며 나중에 특정이벤트(해당코드에선 마운트 해제)
가 될경우 return문이 발동되는 것이다.

일반적인 진행은 1~3번이고 4번은 1,3번을 합쳐서 응용한 느낌이라 생각하면된다.
상황에 따라 return문을 활용해 랜더를 원하는 곳에 해주면 된다.

5번

 5번 useEffect의 잘못된 사용 예시() 1.추가 랜더링, 2.무한루프
  useEffect안에서 setState를 사용시 재 랜더링이 발생한다.
  어쩔수 없을 경우가 아니라면 가능하면 빼주는게 좋다.

  // 1. 추가랜더링
  // useEffect(() => {
  //   setCount(10);
  // }, []);

  // 2. 무한루프
  // useEffect(() => {
  //   setCount((prev) => prev + 1);
  // }, [count]);

5번의 경우는 useEffect안에 setState를 넣은 경우이다.
useEffect는 자체적으로도 랜더를 시켜주는 Hooks인데 안쪽에서
setState가 동작할 경우 리랜더링이 되며 서버에 부하를 준다.
5-2번 같은경우엔 State 값인count가 무한루프되는 현상이 발생하기도 한다.

profile
프론트엔드 개발자 지망생 (react/next/js/ts)

0개의 댓글