[ReactJS] React로 영화 서비스 만들기 : 6. Effect

작성:    

업데이트:

카테고리:

태그: , ,

Effect

Effect의 목적

  • state가 변경될 때 function을 매번 호출하여 rerender
  • component가 처음 render될 때만 코드가 실행되길 원한다면?
  • useEffect의 사용


useEffect

  • 2개의 argument를 가지는 function
  • App.js 파일에 import 해서 사용
  • useEffect 함수의 첫 번째 인자 : 한 번만 실행될 함수 입력
// react의 useEffect를 이용해 import
import { useState, useEffect } from "react";

function App() {
  const [counter, setValue] = useState(0);
  const onClick = () => setValue((prev) => prev + 1);
  console.log("i run all the time");
  const iRunOnlyOnce = () => {
    console.log("i run only once.");
  };
  useEffect(iRunOnlyOnce, []);
  ...
}

위와 같이 작성하면

const iRunOnlyOnce = () => {
  console.log("i run only once.");
};

함수는 다른 state가 변화하더라도 한 번만 실행된다.


useEffect의 array

두번째 argument 자리의 []는 뭔가요?

코드의 특정 부분이 변화할 때마다 그에 적합한 특정 코드들만을 실행하는 방법

const iRunOnlyOnce = () => {
  console.log("i run only once.");
};
useEffect(iRunOnlyOnce, []);

기존 useEffect의 코드를 함수를 따로 정의하여 지정한 것을 아래와 같이 함축한다.

useEffect(() => {
  console.log("CALL THE API...");
}, []);

기존 사이트가 처음 실행될 때 API를 call한다는 의미로 console.log의 텍스트를 바꿔주었다.


검색을 하는 코드를 만들었다.

function App() {
  // const [counter, setValue] = useState(0);
  const [keyword, setKeyword] = useState("");
  // const onClick = () => setValue((prev) => prev + 1);
  const onChange = (event) => setKeyword(event.target.value);
  // console.log("i run all the time");
  // useEffect(() => {
  //   console.log("i run only once.");
  // }, []);
  useEffect(() => {
    console.log("SEARCH FOR", keyword);
  }, [keyword]);
  return (
    <div>
      <input
        value={keyword}
        onChange={onChange}
        type="text"
        placeholder="Search here..."
      />
      // <h1>{counter}</h1>
      // <button onClick={onClick}>click me</button>
    </div>
  );
}
  • 주석처리를 하지 않은 코드에 집중해보자.
  • keyword라는 state를 useState를 이용해 만들어주었다.
  • input 태그의 값을 keyword로 설정
  • 이 keyword가 바뀔때마다 onChange 함수 호출
  • onChange 함수 : keyword state를 event.target.value로 지정하는 함수


keyword가 변화할 때마다 함수가 실행되게 하고 싶다.

  • useEffect를 하나 더 만든다.
  • 2번째 argument array에 keyword state 입력

즉, [] 내의 변수가 변화할 때마다 코드 실행!!

  • 물론 []는 array이므로 2개 이상의 변수도 입력 가능
  • 이 array를 DependencyList라고 한다.
  • dependencies: react.js가 지켜보아야 하는 대상


정리

useEffect

원할 때만 특정 코드를 실행하기 위한 tool


argument

  • 첫 번째(EffectCallback) : 실행하고자 하는 코드/함수
  • 두 번째(DependencyList) : 변화하면 EffectCallback 실행


기타

  • DependencyList에는 2개 이상의 state 입력 가능
  • DependencyList가 비어있다면 새로고침 시에만 실행


Cleanup function

component가 삭제(destory)될 때도 코드를 실행하는 것

function Hello() {
  useEffect(() => {
    // 생성될 때 'created :)'를 출력하는 코드
    console.log("created :)");
    // 제거될 때 'destroyed :('를 출력하는 코드 (함수 호출)
    return () => console.log("destroyed :(");
  }, []);
  return <h1>Hello</h1>;
}

function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => setShowing((prev) => !prev);
  return (
    <div>
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}
  • bool type state인 showing의 상태에 따라 컴포넌트를 create하거나 destroy
  • button을 클릭하면 onClick 함수에 의해 setShowing modifier에 의해 showing 반전
  • Hello component의 useEffect에 집중

  • DependencyList가 비어있으므로 생성시에만 실행
  • useEffect에 의해 console.log(“created :)”); 실행
  • JSX 문법에 의한 react component 반환, 화면에 render
  • 이후 제거될 때 console.log(“destroyed :(“); 실행


arrow function이 아닌 함수형으로 작성해보자

function Hello() {
  function byFn() {
    console.log("destroyed :(");
  }

  function hiFn() {
    console.log("created :)");
    return byFn;
  }
  useEffect(hiFn, []);
  return <h1>Hello</h1>;
}
  • 생성될 때 실행되는 hiFn 함수가 byFn을 호출하며 종료


전체 코드

import { useState, useEffect } from "react";

function App() {
  const [counter, setValue] = useState(0);
  const [keyword, setKeyword] = useState("");
  const onClick = () => setValue((prev) => prev + 1);
  const onChange = (event) => setKeyword(event.target.value);
  console.log("i run all the time");
  useEffect(() => {
    console.log("i run only once.");
  }, []);
  useEffect(() => {
    if (keyword.length > 5) {
      console.log("SEARCH FOR", keyword);
    }
  }, [keyword]);
  return (
    <div>
      <input
        value={keyword}
        onChange={onChange}
        type="text"
        placeholder="Search here..."
      />
      <h1>{counter}</h1>
      <button onClick={onClick}>click me</button>
    </div>
  );
}

댓글남기기