티스토리 뷰

<유의해야할 기본 Rule>

  • JSX에서 JavaScript를 쓸 때에는 {}중괄호 안에 자바스크립트를 써야 한다. 
  • component는 단지 jsx를 부르는 function(함수)일 뿐이다.

 

react.js는 state를 변화시킬 때 component를 재실행(refresh)시킨다. -> 모든 코드가 재실행된다. UI의 관점으로 보면,  새로운 데이터가 들어올 때마다 자동으로 새로고침되니 좋은 일이라고 할 수 있다. 하지만 성능적으로 좋다고 할 수 있을까? 

  • 처음에만 실행되고 그 이후에는 state가 변경이 있더라도 실행되지 않게 하는 방법을 알아야 한다. 내 컴포넌트 내부의 몇몇 코드는 처음 딱 한번만 실행되고 다시는 실행되지 않도록 하고 싶을 수 있기 때문이다. e.g.) API불러오기
  • 또한, 특정한 코드만 변화했을 때 원하는 코드들을 실행할 수 있도록 언제 코드가 실행될 지 결정하는 방법을 알아야 합니다. e.g.) 검색창에 입력값을 반영할 때, 다른 컴포넌트들도 같이 렌더링되기 때문에

-> React.js에서 제공하는 useEffect 함수를 사용하면 해당 문제가 해결된다.

useEffect ?

-react.js 에서 제공하는 함수, Hook

-사용목적: 렌더링이 될 때마다 실행되는 것을 방지하고 원하는 경우에만 함수를 실행시키기 위함, react.js가 동작하는 관점에서 말하자면 방어막같은 것 

-2개의 인자를 갖는다. 

  • 1번째 arg: EffectCallback //함수 
  • 2번째 arg: deps //의존값(dependencies)이 들어있는 배열입니다. ->이 값이 변경되는지 react가 지켜봅니다. 
    • array(배열)이기 때문에 의존값을 여러개 넣을 수 있습니다. e.g)[keyword, counter] // 둘 중에 하나라도 변화가 일어나면 첫번째 인자로 준 함수를 실행시킨다. 

2번째 인자의 배열은 react.js가 지켜보는 대상을 말합니다. 특정 값을 넣게된다면 컴포넌트가 처음 실행될때도 호출이 되고, 지정한 값이 바뀔 때에도 호출된다. 그리고 deps안에 특정 값이 있다면 언마운트시에도 호출이되고, 값이 바뀌기 직전에도 호출이 된다.

 

-useEffect 에서는 함수를 반환 할 수 있는데 이를 cleanup함수라고 부른다. cleanup함수는 useEffect에 대한 뒷정리를 해준다. deps가 비어있는 경우에는 컴포넌트가 사라질 때 cleanup함수가 호출됨 

 

 

 

App.js

  • 위에 import는 CRA를 사용하면 자동으로 생성되는 코드이다. 그렇기 때문에 기존에 우리가 useState를 사용할 때, React.useState() 로 앞에 객체(React)를 써줬으나 임포트를 통해 써줄 필요가 없어진다.  
import { useEffect, useState } 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);

  useEffect(() => {
    console.log('I run only once');
  }, []);

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

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

  useEffect(() => {
    console.log('I run when counter & keyword changes');
  }, [counter, keyword]);
  return (
    <div>
      <input
        value={keyword}
        onChange={onChange}
        type="text"
        placeholder="Search here..."
      />
      <h1>{counter}</h1>
      <button onClick={onClick}>Click me</button>
    </div>
  );
}

export default App;

 

▼첫번째 인자인 함수의 내용에 조건문을 붙여서 아래와 같이 활용할 수 있습니다. 

 //두번째 인자가[] 빈배열일때는 react가 지켜봐야할 것이 없기때문에 처음 한번만 실행됨
  useEffect(() => {
    console.log('I run only once');
  }, []);
  //두번째인자인 배열에 keyword라고 써놓는 것: keyword가 변화할 때 코드를 실행할 거라고 react.js에게 알려주는 것
  //if절을 사용해서 조건을 붙여주면 5글자가 이상일때와 keyword가 공백이 아닐때만 실행된다. 
  useEffect(() => {
    if (keyword !== '' && keyword.length > 5) {
      console.log('SEARCH FOR... ', keyword);
    }
  }, [keyword]);

 

Cleanup 함수

-useEffect의 subscription을 종료할 때, 컴포넌트가 unmount될 때 실행할 로직은 useEffect의 EffectCallback에서 반환되는 함수로 구현한다. 여기서 반환되는 함수를 cleanup function이라 부르고 메모리 누수를 방지하기 위해 사용된다. 

-새로 렌더링한 이후 실행된다.(불확실한 정보 => 초기값이 return null로 되어있다고 생각하자) 이 때, 렌더링은 값이 변하여 새로운 것을 그려주거나 컴포넌트를 없애는 경우가 잇다. useEffect는 리렌더링 이후 클린업을 마치고 실행된다.  

-component가 언제 생성됐고 언제 삭제되는지 알 수 있다. 

예를들어,  cleanup함수를 이용하면 컴포넌트가 사라질 때 해당 내용을 분석 API로 보낼수도 있고 이벤트리스너를 지우거나 혹은 console.log에 뭔가를 보여줄 수도 있다. 

 

※클린업 함수는 자주 사용하지는 않으나 알고있으면 차후에 유용하게 사용할 수 있는 개념의 함수입니다. 

 

 

import { useEffect, useState } from 'react';

function Hello() {
  useEffect(() => {
    console.log('created');
    return () => console.log('destroyed');
  }, []);
  return <h1>🌹🌹🌹</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>
  );
}

export default App;
  • useEffect의 첫번째 인자로 들어간 함수에서 return해주는 return () => console.log("destoryed")가 바로 cleanup함수이다. 
  • Hello 컴포넌트를 hide할 때는 컴포넌트가 스크린에서 지워지고 show를 누르면 컴포넌트가 다시 생성되므로 useEffect도 다시 실행된다. 여기서 중요한 점은 컴포넌트가 생성될 때 말고 없어질 때에도 코드를 실행할 수 있다는 점이다. return값으로 함수를 주면된다. useEffect는 함수를 받고, 이 함수는 dependency가 변화할 때 호출된다. 현재는 dependenct가 비어있으니 컴포넌트가 처음 생성될 때 함수가 호출된 후 다시 호출되지 않음 그래서 컴포넌트가 파괴될 때도 함수를 실행하고 싶다면 useEffect 함수가 새로운 함수를 return해야 한다. -> deps가 비어있으면 자동으로 컴포넌트가 파괴될 때 cleanup함수가 실행되는데 그 과정이 리렌더링으로 useEffect함수가 실행되고 클린업하면서 이전에 있던 이펙트인 console.log("created")가 삭제되고 새로운 이펙트 함수인 return함수가 실행되기 때문이다.

+ 화살표 함수와 아닌 코드를 비교해보세요. 간결해지지만 생략돼있어서 이해가 안될수도 있습니다. 해당 표현 방식은 같은 작동을 하는 코드들입니다. 

//익명함수 화살표 함수 사용
useEffect(() => {
    console.log('created');
    return () => console.log('destroyed');
  }, []);


//안 사용한 것
function byFn() {
 console.log("bye");
}
function hiFn() {
console.log("hi");
return byFn;
}
useEffect(hiFn, []);

//익명함수 화살표 함수 사용X ver
useEffect(function () {
console.log('created');
return function () {
console.log('destroyed');}}, []);

▼useEffect 관련 상세설명 참고자료

https://react.vlpt.us/basic/16-useEffect.html

 

16. useEffect를 사용하여 마운트/언마운트/업데이트시 할 작업 설정하기 · GitBook

16. useEffect를 사용하여 마운트/언마운트/업데이트시 할 작업 설정하기 이번에는 useEffect 라는 Hook 을 사용하여 컴포넌트가 마운트 됐을 때 (처음 나타났을 때), 언마운트 됐을 때 (사라질 때), 그리

react.vlpt.us

 

 

댓글