Effect Hook

Jelkov Ahn·2021년 10월 20일
0

React

목록 보기
8/10
post-thumbnail

<HOOK 사용코드 예시>

import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const proverbs = [
    "좌절감으로 배움을 늦추지 마라",
    "Stay hungry, Stay foolish",
    "Memento Mori",
    "Carpe diem",
    "배움에는 끝이 없다"
  ];
  const [idx, setIdx] = useState(0);

  const handleClick = () => {
    setIdx(idx === proverbs.length - 1 ? 0 : idx + 1);
  };

  return (
    <div className="App">
      <button onClick={handleClick}>명언 제조</button>
      <Proverb saying={proverbs[idx]} />
    </div>
  );
}

function Proverb({ saying }) {
  useEffect(() => {
    document.title = saying;
  });
  return (
    <div>
      <h3>오늘의 명언</h3>
      <div>{saying}</div>
    </div>
  );
}

Hook을 쓸 때 주의할 점

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

단 한번만 실행되는 Effect 함수

    1. 빈 배열 넣기 : useEffect(함수, [])
      빈 배열을 useEffect의 두 번째 인자로 사용하면, 이 때에는 컴포넌트가 처음 생성될때만 effect 함수가 실행됩니다
    1. 아무것도 넣지 않기 (기본 형태) : useEffect(함수)
      컴포넌트가 처음 생성되거나, props가 업데이트되거나, 상태(state)가 업데이트될 때 effect 함수가 실행됨

Data Fetching

  • 컴포넌트 내에서 필터링: 전체 목록 데이터를 불러오고, 목록을 검색어로 filter 하는 방법
import { useEffect, useState } from "react";
import "./styles.css";
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">
      필터
      <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>;
}
  • 컴포넌트 외부에서 필터링: 컴포넌트 외부로 API 요청을 할 때, 필터링한 결과를 받아오는 방법 (보통, 서버에 매번 검색어와 함께 요청하는 경우가 이에 해당합니다)
import { useEffect, useState } from "react";
import "./styles.css";
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>;
}

Loading indicator의 구현

const [isLoading, setIsLoading] = useState(true);

// 생략, LoadingIndicator 컴포넌트는 별도로 구현했음을 가정합니다
return {isLoading ? <LoadingIndicator /> : <div>로딩 완료 화면</div>}
useEffect(() => {
  setIsLoading(true);
  fetch(`http://서버주소/proverbs?q=${filter}`)
    .then(resp => resp.json())
    .then(result => {
      setProverbs(result);
      setIsLoading(false);
    });
}, [filter]);
profile
끝까지 ... 가면 된다.

0개의 댓글