[React]Effect Hook

도시·2022년 6월 30일
0

React

목록 보기
6/11

1. Effect Hook

📝 Side Effect (부수효과)

  • Side Effect란, React 컴포넌트가 화면에 렌더링된 이후 비동기로 처리되어야 하는 부수적인 효과들을 말한다.
  • 함수 내에서 어떤 구현이 함수 외부에 영향을 끼치는 경우, 해당 함수는 Side Effect가 있다고 이야기한다.
  • React 컴포넌트 내에서 fetch를 사용하여 API를 가져오거나, 이벤트를 활용해 DOM을 조작할 때 Side Effect가 발생한다.
  • 아래 코드에서는 전역변수 foo를 함수 bar()가 수정하고 있다. 그러므로 bar()는 Side Effect를 발생시킨다.
let foo = 'hello';
function bar() {
  foo = 'world';
}
bar();

👉 Pure Function(순수 함수)

  • Pure Function이란, 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수를 의미한다.
  • 순수 함수는 입력으로 전달된 값을 수정하지 않는다.
  • 함수의 입력이 아닌 다른 값이 함수의 결과에 영향을 미치는 경우, 순수 함수라 할 수 없다.
  • 순수함수는 어떠한 전달 인자가 주어질 경우, 항상 똑같은 값이 리턴됨을 보장하기 때문에 예측 가능한 함수이다.
function upper(str) {
  // toUpperCase 메소드는 원본을 수정하지 않음 (Immutable)
  return str.toUpperCase(); 
}
upper('hello') // 'HELLO'

👉 React의 함수 컴포넌트

  • React의 함수 컴포넌트는 Side Effect 없이 순수 함수로 작동한다.
function SingleTweet({ writer, body, createdAt }) {
  return <div>
    <div>{writer}</div>
    <div>{createdAt}</div>
    <div>{body}</div>
  </div>
}
  • 하지만, React에서 AJAX 요청이 필요하거나 LocalStorage, 타이머와 같은 API를 사용하는 경우 Side Effect가 된다.
    React 컴포넌트에서의 Side Effect가 발생하는 경우
    타이머 사용 (setTimeout)
    데이터 가져오기 (fetch API, localStorage)

  • 이 때문에 React에서 Side Effect를 다루기 위한 Hook인 Effect Hook을 제공한다.


📝 Effect Hook 개념

  • useEffect는 컴포넌트 내에서 Side Effect를 실행할 수 있게 하는 Hook이다.
  • useEffect의 첫 번째 인자는 함수이다. 해당 함수 내에서 Side Effect를 실행한다.
  • 매번 새롭게 컴포넌트가 렌더링 될 때 Effect Hook이 실행된다.
    👉 컴포넌트 생성 후 처음 화면에 렌더링(표시)
    👉 컴포넌트에 새로운 props가 전달되며 렌더링
    👉 컴포넌트에 상태(state)가 바뀌며 렌더링

❌ Hook 사용시 주의점 ❌

  • 최상위에서만 Hook을 호출한다.
  • React 함수 내에서 Hook을 호출한다.

📝 Effect Hook 조건부 실행

  • useEffect의 두 번째 인자는 배열이다. 이 배열은 조건을 담고있으며, 조건은 boolean 형태가 아닌 어떤 값의 변경이 일어날 때를 의미한다.

단 한 번만 실행되는 Effect 함수

  • 두 번째 배열을 빈 배열 []로 둘 경우
    useEffect(함수, [])
    👉 컴포넌트가 처음 생성될 때만 effect 함수가 실행된다.
    👉 이 방법은 대표적으로, 맨 처음 외부 API를 통해 리소스를 받아오고 더 이상 API 호출이 필요하지 않을 때에 사용할 수 있다.

  • 아무것도 넣지 않을 경우 (기본 형태)
    useEffect(함수)
    👉 컴포넌트가 처음 생성되거나, props나 state가 업데이트될 때 실행


📝 컴포넌트 내에서의 AJAX 요청

Data Fetching

  1. 컴포넌트 내에서 필터링: 전체 목록 데이터를 불러오고, 목록을 검색어로 filter 하는 방법
  • 처음에 한 번만 외부 API로부터 명언 목록을 받아오고, filter 함수를 이용
import { useEffect, useState } from "react";
import { getProverbs } from "./storageUtil";
export default function App() {
  const [proverbs, setProverbs] = useState([]);
  const [filter, setFilter] = useState("");
  useEffect(() => {
    console.log("언제 effect 함수가 불릴까???");
    const result = getProverbs();
    setProverbs(result);
  }, []);
  const handleChange = (e) => {
    setFilter(e.target.value);
  };
  return (
    <div className="App">
      <span>필터</span>
      <input type="text" value={filter} onChange={handleChange} />
      <ul>
        {proverbs.filter((prvb) => {
            return prvb.toLowerCase().includes(filter.toLowerCase());
          }).map((prvb, i) => (
            <Proverb saying={prvb} key={i} />
          ))}
      </ul>
    </div>
  );
}
function Proverb({ saying }) {
  return <li>{saying}</li>;
}
  1. 컴포넌트 외부에서 필터링: 컴포넌트 외부로 API 요청을 할 때, 필터링 한 결과를 받아오는 방법
  • 검색어가 바뀔 때마다, 외부 API를 호출
import { useEffect, useState } from "react";
import { getProverbs } from "./storageUtil";
export default function App() {
  const [proverbs, setProverbs] = useState([]);
  const [filter, setFilter] = useState("");
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log("언제 effect 함수가 불릴까???");
    const result = getProverbs(filter);
    setProverbs(result);
  }, [filter]);
  const handleChange = (e) => {
    setFilter(e.target.value);
  };
  const handleCounterClick = () => {
    setCount(count + 1);
  };
  return (
    <div className="App">
      필터
      <input type="text" value={filter} onChange={handleChange} />
      <ul>
        {proverbs.map((prvb, i) => (
          <Proverb saying={prvb} key={i} />
        ))}
      </ul>
      <button onClick={handleCounterClick}>카운터 값: {count}</button>
    </div>
  );
}
function Proverb({ saying }) {
  return <li>{saying}</li>;
}

컴포넌트 내에서 필터링과 컴포넌트 외부에서 필터링의 차이점

장점단점
컴포넌트
내부에서 처리
HTTP 요청의 빈도를 줄일 수 있다브라우저(클라이언트)의 메모리 상에 많은 데이터를 갖게 되므로, 클라이언트의 부담이 늘어난다
컴포넌트
외부에서 처리
클라이언트가 필터링 구현을 생각하지 않아도 된다빈번한 HTTP 요청이 일어나게 되며, 서버가 필터링을 처리하므로 서버가 부담을 가져간다

profile
UI·UX Designer/Frontend Dev

0개의 댓글