리액트 스터디

[React] 9. 리액트 스터디 - effect

더밸류(THEVALUE) 2023. 1. 3. 10:38

컴포넌트에 이벤트 발생 시 / state에 변화를 감지한 경우 

컴포넌트는 다시 그려짐 (리랜더링)

반복되는 랜더링을 방지하고자 사용하는 문법

 

- 아래 예제는 콘솔 로그가 버튼 클릭 때 마다 호출이 됨

import { useState } from "react";

function App() {
  const [counter, setValue] = useState(0);
  const onClick = () => setValue((current) => current + 1);
  console.log("render");
  return (
    <div>
      <h1>{counter}</h1>
      <button onClick={onClick}>Click Me!!</button>
    </div>
  );
}

export default App;

 

[ useEffect ]

 

컴포넌트가 랜더링 될 때 특정 작업을 수행하도록 설정하는 hook (리액트 문법)

- 아래 예제에서는 input 텍스트 박스에 6글자 이상의 글자를 입력한 경우처럼 특정한 경우에만 console 로그를 찍도록 처리 

 

문법
useEffect(() => {}, []);
1번째 인자 : 함수 형태로 설정
2번째 인자 : 상태 값의 변경이나 이벤트를 감지할 대상을 설정, 배열 형태로 설정 
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);
  // event가 발생할 때 마다 호출됨
  console.log("call an api");
  // 1회만 호출되도록 함 
  // useEffect
  // [] 배열에 아무런 값이 없으므로 최초 1회만 감시 
  useEffect(() => {
    console.log("i once");
  }, []);

  // keyword 의 상태값이 변경될 때마다 실행
  // counter 의 상태값이 변경될 때에는 영향을 받지 않음
  useEffect(() => {
    // keyword가 비어 있지 않으면서 길이가 5를 초과할 경우부터 호출
    if(keyword !== "" && keyword.length > 5) {
      console.log("SEARCH FOR", keyword);
    }
  }, [keyword]);

  // counter 의 변화를 감지
  useEffect(() => {
      console.log("counter FOR", counter);
  }, [counter]);

  // keyword & counter 를 둘다 체크 
  useEffect(() => {
    console.log("test");
}, [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;

 

[ cleanup function ]

컴포넌트가 destroy 될 때 실행하도록 처리한 함수 
많이 사용은 안할테지만 jQuery에서 콜백함수와 비슷하게 사용할 수 있을 것 같아서 기록
import { useState, useEffect } from "react";

function Hello() {
  useEffect(() => {
    console.log("Im Here!");
    // cleanup function
    return () => console.log("detroyed func");
  }, []);
  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>
  );
}

export default App;