[20220530_useEffect hook]

YunTrollpark·2022년 5월 30일
0

React

목록 보기
3/12

useEffect

1. 언제 사용?

Mount(화면에 첫 렌더링), Update(다시 렌더링), Unmount(화면에서 사라질때) 될때 특정 작업을 처리할 코드를 실행시키고 싶다면 useEffect사용

2. useEffect의 형태

useEfect(() => {})

기본적으로 useEffect hook은 인자로 callback함수를 받음

callback함수란 다른 함수의 인자로 전달된 함수를 의미
callback 함수 내부에 우리가 원하는 작업을 처리해줄 코드를 작성

useEffect(() => {//작업...})
  
  1️⃣ useEffect(() => {//작업...}); //useEffect의 인자로 하나의 callback 함수만 받음
  2️⃣ useEffect(() => {//작업}, [value]); //useEffect의 첫번째 인자로 callback함수,
                                       //두번째 인자로 배열을 받음(이 배열을 다른말로 dependency array라고 함)
1️⃣ useEffect(() => {//작업...});
              //특징: 렌더링 될때 마다 매번 callback 실행
              //컴포넌트가 맨처음 화면에 렌더링이 될때, 컴포넌트가 다시 렌더링 될때 실행
2️⃣ useEffect(() => {//작업...}, [value]);
               //특징: 화면에 첫 렌더링이 될때 실행
               // 배열안에 value값이 바뀔때만 실행
              // 빈배열 전달시, 화면에 첫 렌더링 될때 실행

3. clean up - 정리

useEffect(() => {//구독...}, []);

• 만약 useEffect에서 어떤 서비스를 구독하는 코드를 넣었다면,
• 이후 '구독해제'를 하는 clean up 정리 작업을 처리 해줘야함
• 만약 타이머를 시작했다면, 더이상 타이머를 사용할 필요가 없을때 타이머를 멈추는 정리 작업을 해줘야함
• 만약 이벤트 리스너를 등록했다면, 등록한 리스너를 제거 해주는 정리 작업을 해야함

//이걸 정리하려면 useEffect에 return값으로 함수 추가
//함수 안에서 우리가 원하는 정리하는 작업을 처리해주면 됨
// 이렇게 함수를 return을 해주면 해당 컴포넌트가 unmount 될때, 혹은 다음 렌더링시 불릴 useEffect가 실행되기 이전에 그 함수가 실행
useEffect(() => {//구독...
return () => {
//구독해지...
   }
},[]);

예시

  1. 예시
import React, {useState, useEffect} from 'react';

function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
  
  const handleCountUpdate = () => {
  setCount(count + 1);
  };
  
  const handleInputChange = (e) => {
  setName(e.target.value);
  }
  
  useEffect(() => {
  //..여기 들어가는 callback 안에 들어가는 부분은 우리의 컴포넌트가 렌더링 될때마다 매번 실행
    console.log('렌더링🍎')
  })
  
  return (
  <div>
    <button onClick={handleCountUpdate}>Update</button> //업데이트 버튼
    <span>count: {count} </span>  //현재 카운트가 몇개인지 보여주는 span태그
    <input type="text" value={name} onChange={handleInputChange}/>
    <span>name: {name}</span>
  </div>
  );
}
//input안에 값이 업데이트 될때마다 handleInputChange라는 함수가 불림 → 그리고 그 안에
//있는 setName이 불림 → 그러면 name state안에 있는 값이 계속해서 업데이트 됨 → 입력할때마다 계속 렌더링 됨 →
//그러면 useEffect 안에 있는 callback이 계속 불림 →그러면 계속 렌더링되니까 무거워짐

export default App;
  1. 예시
import React, {useState, useEffect} from 'react';

function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
  
  const handleCountUpdate = () => {
  setCount(count + 1);
  };
  
  const handleInputChange = (e) => {
  setName(e.target.value);
  }
  
  //만약 name의 업데이트는 무시하고 count가 업데이트 될때만 useEffect를 실행하고 싶다면?
  //→ useEffect의 두번째 인자로 배열을 주면 됨
c
  useEffect(() => {
    console.log('count 변화 🍎')
  }, [count]); //배열안에는 count를 주면 됨
  // -> 이렇게 두번째 인자로 배열을 주게 되면 맨처음 컴포넌트가 렌더링됐을 때, count가 업데이트 됐을때만 실행

 // 마운트 + [name] 변경될때만 실행!
    useEffect(() => {
    console.log('name 변화 🍎')
  }, [name]);
  
   // 렌더링 마다 매번 실행, 렌더링 이후
    useEffect(() => {
    console.log('렌더링 🍎')
  });
  
  // useEffect를 맨처음 화면에 렌더링(mount) 될때만 실행하고 싶으면 2번째 인자로 빈배열!
    useEffect(() => {
    console.log('마운팅 🍎')
  }, []);
  
  return (
  <div>
    <button onClick={handleCountUpdate}>Update</button>
    <span>count: {count} </span>
    <input type="text" value={name} onChange={handleInputChange}/>
    <span>name: {name}</span>
  </div>
  );
}

export default App;

clean up 예시

//Timer component

import React, {useEffect} from 'react';

const Timer = (props) =>{
  
  useEffect(() => { //Timer component가 맨처음 화면에 렌더링 됐을때만 실행
  const timer  = setInterval(() => {
    console.log("타이머 돌아가는 중");
  }, 1000);//1초마다 한번씩 반복
    
    return () => {
      //여기에 정리 작업을 해줄 코드를 넣어줌
     //타이머 컴포넌트가 unmount될때, 화면에서 사라질때 실행
      clearInterval(timer); // 인자로 우리가 만들어준 timer를 넣음(swtInterval을 끝내줌)
      console.log('타이머가 종료됐습니다');
    }
    
  }, []);
  
  return(
  <div>
    <span>타이머를 시작합니다. 콘솔을 보세요!</span>
  </div>
  );
  //이렇게 작성하면 타이머가 브라우저에 맨처음 마운팅 됐을때만 useEffect 내부의 callback함수 실행(setInterval의 인자로 들어간 callback을 1초마다 반복해서 부름)
};
import React, {useState, useEffect} from 'react';
import Timer from './component/Timer';

function App() {
  
  const [showTimer, setShowTimer] = useState(false);
  
  return (
  <div>
    {showTimer && <Timer />}//showTimer가 true일때만 실행
    <button onClick={() => setShowTimer(!showTimer)}>Toggle Timer</button> //이 버튼이 클릭될때마다 showTimer가 flase라면 true로 바껴야 하고
    //true면 false로 바껴야함. 그래서 onClick에 반전값을 줌
  </div>
  );
}


export default App;
profile
코딩으로 세상에 이야기하는 개발자

0개의 댓글