[React] useEffect

요들레이후·2023년 1월 9일
0

React

목록 보기
2/2
post-thumbnail

💡 useEffect를 사용하여 마운트(처음 나타났을 때)/언마운트(사라질 때)/업데이트시(특정 props가 바뀔 때) 할 작업 설정하기
참고링크 : https://goddaehee.tistory.com/308
https://ko.reactjs.org/docs/hooks-effect.html

💡 정리
useEffect(() => {}); // 재렌더링마다 코드 실행
useEffect(() => {}, []); // mount시 1회 코드 실행
useEffect(() => {code}, [의존성1, 의존성2, ..]); // 조건부 effect 발생 의존성 배열 바뀔 때
useEffect(() => { return () => {}}); // unmount시 1회 실행

useEffect

  • 컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook
  • 리액트의 useEffect 훅을 사용하면 side effect(데이터 가져오기, 구독 설정하기, 수동으로 dom 수정하기..etc)를 사용 가능
  • 클래스형 컴포넌트에서의 라이프사이클 훅을 대체 가능

useEffect가 하는 일?

useEffect Hook을 이용해 React에게 컴포넌트가 렌더링 이후에 어떤 일을 수행하는 지 알려줌.

React는 우리가 넘긴 함수(effct)를 기억했다가 DOM업데이트를 수행한 이후에 불러낼 것.

이 외에도 데이터를 가져오거나 다른 명령형 API를 불러내는 일을 할 수 있다.

useEffect를 컴포넌트 안에서 불러내는 이유?

effect를 통해 state변수에 접근할 수 있기 때문.

함수 범위 안에 존재하기 때문에 특별한 API 없이도 값을 얻을 수 있다.

useEffect는 렌더링 이후에 매변 수행되나?

맞다. 기본적으로 첫번째 렌더링과 이후의 모든 업데이트에서 수행된다.

마운팅과 업데이트라는 방식으로 생각하는 대신 effect를 렌더링 이후에 발생하는 것으로 생각

1. 선언 방법

  • 첫 번째 인자(effect)는 함수, 두번째 인자는 배열(deps)가 들어감
import react, {useEffect} from "react";
useEffect(effect, [, deps]);

2. 렌더링 되는 방식 - effect를 필요에 맞게 수정

1) effect

  • 렌더링 이후 실행할 함수(리액트는 이 함수를 기억했다가 DOM 업데이트 후 불러낸다.)
  • effect함수에서 함수를 return할 경우 그 함수가 컴포넌트가 Unmount될 때 정리의 개념으로 한 번 실행된다.

📌 ex1) 렌더링이 완료될 때마다 실행되는 예시

useEffect(() => {
	// 수행할 함수
});
  • componentDidMount & componentDidUpdate를 함께 표현
import React, { useState, useEffect } from "react";

const Practice = () => {
  const [count, setCount] = useState(0);
  const countUp = () => setCount(count + 1);

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

  return (
    <div>
      <p>{count}번 클릭!</p>
      <button onClick={countUp}>Click Me</button>
    </div>
  );
};

export default Practice;

→ 렌더링이 되었을 때, count가 변경될 때마다 console.log찍힘

2) deps

  • 배열의 형태로, 특정한 값이 변경될 때 effect 함수를 실행하고 싶은 경우 배열 안에 그 값을 넣어준다.

📌 ex2) 최초 렌더링시에만 실행되는 예시

useEffect(() => {
	// 수행할 함수
}, 빈배열);
import React, { useState, useEffect } from "react";
  • componentDidMount와 유사하게 볼 수 있다.
const Practice = () => {
  const [count, setCount] = useState(0);
  const countUp = () => setCount(count + 1);

  useEffect(() => {
    console.log("useEffect!!", count);
  }, []);

  return (
    <div>
      <p>{count}번 클릭!</p>
      <button onClick={countUp}>Click Me</button>
    </div>
  );
};

export default Practice;

📌 ex3) 화면에 첫 렌더링 될 때 & 특정 값이 변경될 때에만 실행하는 경우

useEffect(() => {
	// 수행할 함수
}, 특정배열);
import React, { useState, useEffect } from 'react';

const Practice = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('hayeong');
  const countUp = () => setCount(count + 1);
  const handleChangeName = (e) => setName(e.target.value);

  useEffect(() => {
    console.log('useEffect!!', count);
  }, [count]);

  return (
    <div>
      <p>안녕하세요, {name}입니다.</p>
      <input onChange={handleChangeName} />
      <p>{count}번 클릭!</p>
      <button onClick={countUp}>클릭</button>
    </div>
  );
};

export default Practice;
  • name의 값이 변경될 때에는 console.log가 동작하지 않음

  • count값이 변경될 때에는 log가 찍힘

cleanup 함수

  • useEffect 안에서 return 할 때 실행된다.(useEffect의 뒷정리)
  • 네트워크 리퀘스트, DOM 수동 조작, 로깅 등은 정리(clean-up)가 필요 없는 경우이다. 이러한 예들은 실행 이후 신경 쓸 것이 없기 때문이다.
  • 만약 컴포넌트가 마운트 될 때 이벤트 리스너를 통해 이벤트를 추가하였다면,
    컴포넌트가 언마운트 될 때 이벤트를 삭제 해주어야 한다.
    ⇒ 다음 차례의 effect를 실행하기 전에 이전의 렌더링에서 파생된 effect정리
  • 그렇지 않으면 컴포넌트가 리렌더링 될 때마다 새로운 이벤트 리스너가 핸들러에 바인딩 될 것이다. 이는 자주 리렌더링 될 경우 메모리 누수가 발생할 수 있다.
useEffect(() => {
	// 함수 처리부
    return () => {
    	// cleanup => 정리 작업 실행
    }
}, 배열);
import React, { useState, useEffect } from 'react';

const Exercise = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('hayeong');
  const countUp = () => setCount(count + 1);
  const handleChangeName = (e) => setName(e.target.value);

  useEffect(() => {
    console.log('useEffect!!', count);
    return () => {
      console.log('cleanup!!', count);
    };
  }, [count]);

  return (
    <div>
      <p>안녕하세요, {name}입니다.</p>
      <input onChange={handleChangeName} />
      <p>{count}번 클릭!</p>
      <button onClick={countUp}>클릭</button>
    </div>
  );
};

export default Exercise;

  • 클릭 시 cleanup 함수에서는 이전 count값, 그리고 렌더링 이후 변경된 count 값이 찍히는 것을 볼 수 있다.
  • useEffect 함수가 다시 실행될 때(실행되기 직전), return 함수를 먼저 실행해주고 넘어가는 것으로 볼 수 있다.
  • 즉, return 함수를 추가하여 componentWillUnmount 역할을 할 수 있다.
profile
성공 = 무한도전 + 무한실패

0개의 댓글