React

useEffect

sangchu 2023. 2. 19. 15:03

Introduction

state를 변경하면 모든 component는 다시 실행되고 모든 code들도 다시 실행된다.

const App = () => {
      const [counter, setCounter] = React.useState(0);
      const onClick = () => setCounter((current) => current + 1);
      console.log("call an api");
      return (
        <div>
          <h3>{counter}</h3>
          <button onClick={onClick}>Click me</button>
        </div>
      );
    };

리렌더링 될 때마다 반복 실행되어도 괜찮은 코드도 있을 테지만, 컴포넌트가 처음 render 될 때만 코드가 실행되길 원할 수도 있다. 예를들어, API로 외부 데이터를 가져올 때 컴포넌트 처음 렌더링되는 그 순간에만 API 요청을 하고 이후에 state가 변화할 때는 그 API에서 똑같은 정보를 가져오고 싶지는 않을 것이다.

이렇게 특정 코드들이 첫번째 component render에서만 실행되게 하려면 useEffect를 사용하면 된다.

 

useEffect

useEffect는 두 개의 argument를 가지는 함수인데, 첫 번째 argument는 실행하고 싶은 코드고, 두 번째는 Deps 배열을 넣는데 이는 dependency(지켜보려는 것)이다. 즉, Deps를 통해 내가 원하는 부분을 지정하여 그 부분만을 변화시킬 수 있다.

Deps부분에 빈 배열을 넣어주면 처음 실행됐을 때만 render된다.

const App = () => {
      const [counter, setCounter] = React.useState(0);
      const onClick = () => setCounter((current) => current + 1);
      console.log("i run all the time");
      const iRunOnlyOnce = () => {
        console.log("i run only once");
      };
      React.useEffect(iRunOnlyOnce, []);
      return (
        <div>
          <h3>{counter}</h3>
          <button onClick={onClick}>Click me</button>
        </div>
      );
    };

참고로 useEffect는 화면이 다 그려지고 나서 실행된다. memo랑 헷갈릴 수 있는데 이는 라이프 사이클이랑 연관이 있는 함수이고, 최초 실행만 할 것이냐, 아니면 props, state에 따라 렌더링시 다시 그릴것이냐 판단하는 함수다.

 

Deps

이번엔 특정 코드가 바뀔 때마다 실행되게 해보자. Deps에 감지하고자 하는 변수를 넣으면 된다.

const App = () => {
      const [counter, setCounter] = React.useState(0);
      const [keyword, setKeyword] = React.useState("");
      const onClick = () => setCounter((current) => current + 1);
      const onChange = () => setKeyword(event.target.value);
      console.log("i run all the time");
      React.useEffect(() => {
        console.log("I run only once.");
      }, []);
      React.useEffect(() => {
        console.log("I run when 'keyword' changes.", keyword);
      }, [keyword]);
      React.useEffect(() => {
        console.log("I run when 'counter' changes.");
      }, [counter]);
      return (
        <div>
          <input
            value={keyword}
            onChange={onChange}
            type="text"
            placehoder="Search here..."
          />
          <h3>{counter}</h3>
          <button onClick={onClick}>Click me</button>
        </div>
      );
    };

아래와 같이 여러개를 지정할 수도 있다.

React.useEffect(() => {
        console.log("I run when 'keyword & counter' changes.");
      }, [keyword, counter]);

이렇게 불필요한 리렌더링을 피하기 위해 React.js가 따로 준비한 것이 바로 useEffect이다.

 

Cleanup function

const Hello = () => {
      React.useEffect(() => {
        console.log("created");
      }, []);
      return <h1>Hello</h1>;
    };

    const App = () => {
      const [showing, setShowing] = React.useState(false);
      const onClick = () => setShowing((prev) => !prev);
      return (
        <div>
          {showing && <Hello />}
          <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
        </div>
      );
    };

Show 버튼을 누를때마다 useEffect가 실행된다.

 

참고로 요소를 숨기는게 아니라 없애버리는 것이다. 다음 사진을 보면 요소가 아예 없어지는 것을 확인할 수 있다.

 

destory될 때 실행할 함수를 지정하려면 useEffect 안에 return을 넣으면 된다.

React.useEffect(() => {
        console.log("created");
        return () => console.log("destroyed")
      }, []);

이제 Hide를 통해 컴포넌트가 없어질 때 해당 함수가 실행된다.

이는 예를 들어 할 일을 다 끝내고 API분석 결과를 보낼 때 사용한다.

 

총 정리

지금까지 배운 것을 간략히 정리하면 다음과 같다. 

  • 리액트를 사용하는 이유: 최소 단위의 렌더링을 위해
  • useState(): 변수, 변수를 제어하는 함수로 구성되며 변하는 값을 제어, 해당 부분의 리렌더링을 위함이다.
  • props: 태그의 속성 값을 함수의 argument처럼 컴포넌트에 값을 전달해준다.
  • 부모 컴포넌트에서 리렌더링이 일어날 경우 모든 자식들이 리렌더링이 된다.(memo를 사용할 수 있다)
  • propType을 설치하고 props의 타입을 지정해 줄 수 있다. 이 때 isRequired로 필수값을 지정할 수 있다.
  • useEffect(): 코드의 실행 시점을 관리할 수 있는 선택권을 얻는 방어막 같은 존재, dependency가 없을 경우 최초 1회 실행, 있을 경우 해당 값이 변할 경우 실행한다. dependency는 여러개 입력이 가능하다.
  • CleanUp 함수를 통해 뒷처리(destory)를 할 수 있다.

 

 

 

참고 : NomadCoders - ReactJS로 영화 웹 서비스 만들기 강좌

'React' 카테고리의 다른 글

props, PropTypes, memo  (0) 2023.02.18
useState를 이용해 단위변환 기능 만들기  (0) 2023.02.18
state, setState  (0) 2023.02.18
[JSCODE] React 3회차 미션  (1) 2023.02.17
[JSCODE] React 2회차 심화미션  (1) 2023.02.14