7. Hooks - Hooks의 개념과 useState, useEffect

dmalk k·2023년 9월 12일

소플의 리액트

목록 보기
18/50

Hooks

- 16.8버전에서부터 나온 기능
- 컴포넌트는 클래스 컴포넌트/ 함수 컴포넌트로 나뉜다

class component(클래스) - 생성자-state, setState()업데이트, Lifecycle methods를 제공

function component(함수) - state사용불가, Lifecycle구현불가

but,

function component에서 Hooks를 쓰면

class component와 동일한 기능을 수행할 수 있다.


Hooks(갈고리) : 기능에 끼어들기. ex)webHook

function MyComponent(props){
 		
  		// Hooks들로 낚아 기능을 수행하게 한다
  		---> Hooks(state 관련함수)

    	---> Hooks(Lifecycle 관련함수)

    	---> Hooks(최적화 관련함수)


	return (
      <div>
      	안녕하세요, 소플입니다.
      </div>
    )
}  

function component에서 state 사용하기

state 사용 전

import React, {useState} from "react";

function Counter(props) {
  var count = 0;

  // count가 증가하기는 하지만 랜더링을 거치지 않으면 값이 초기화 되지 않는다
  return (
    <div>
    	<p>{count}번 클릭했습니다. </p>
		<button onClick={()=> count++}>
          클릭
		</button>
	</div>
  );
}

useState 사용하는 방법

const [변수명, set함수명] = useState(초기값); // class 컴포넌트에서 this.state에 넣은 값

state 사용 후

import React, {useState} from "react";

function Counter(props) {
  const [count, setCount] = useState(0);//	var count = 0;

  return (
    <div>
    	<p>{count}번 클릭했습니다. </p>
 
      		// 클릭시 setCount()함수 실행
		<button onClick={()=> setCount(count+1)}> 클릭 </button>
        		// count를 1증가 시키고, count값이 변경되어 컴포넌트가 다시 랜더링 되면서
        		// 새로운 count값이 화면에 출력된다      
	</div>
  );
}

class 컴포넌트에서
setState()함수를 호출해 state를 업데이트 후
컴포넌트를 재랜더링하는 과정과 동일

차이점
- 클래스 컴포넌트는 setState()함수에서 한번에 모든 state를 변경할 수 있었다
- 함수 컴포넌트는 각 state마다 set함수가 따로 존재한다


#useEffect() :

- class의 생명주기 함수를 묶어놓은 기능이다

- Side effect를 수행하기 위한 Hook

Side effect의 뜻은 부작용이다

but,

리액트에서는 effect(효과, 영향)의 의미가 더 강하다

  • 서버에서 데이터를 받아오기
  • 수동으로 돔을 변경하는 작업

!이 작업들을 effect라고 부르는 이유

  • 다른 컴포넌트에 영향을 미칠 수 있으며,
    렌더링 중에는 작업이 완료될 수 없기 때문

Side effect

이러한 작업이 다른 컴포넌트에 영향없이 사이드(옆에서) 실행된다는 의미이다

즉,

useEffect()는

리액트의 함수 컴포넌트에서 Side effect를 실행할 수 있게 해주는 Hook


useEffect() 사용법

useEffect(이펙트 함수, 의존성 배열);
// 의존성 배열 : 해당 이팩트가 실행되기 위해 의존하고 있는 배열을 말한다
// 배열안의 값중 하나라도 변경되면 effect가 실행된다
// 처음 컴포넌트가 랜더링(mount)된 이후와 업데이트로 인한 재랜더(unMount)링 이후에 실행한다

1)Effect function이 mount, unmount시에 단 한 번씩만 실행 됨

useEffect(이펙트 함수, []);

2)의존성 배열을 생략하면 컴포넌트가 업데이트될 때마다 호출 됨

useEffect(이펙트 함수);

import React, {useState, useEffect } from "react";

function Counter(props) {
  const [count, setCount] = useState(0);
 
  // componentDidMount, componentDidUpdate와 비슷하게 작동
  useEffect(() => {
  	// 브라우저 API를 사용해서 document의 title을 업데이트 합니다.
  	// 크롬 브라우저의 경우 탭에 나오는 내용
    document.title = `You clicked ${count} times`;
  });
 
  return (
  	<div>
      <p>{count}번 클릭했습니다.</p>
      <button onClick={() => setCount(count + 1)}>
        클릭
      </button>
    </div>  
  ); 
}  

리액트는 돔이 변경된 이후에 해당 이팩트 함수를 실행
기본적으로 컴포넌트가 처음 랜더링 될때를 포함해서 매번 랜더링 될때마다 이팩트가 실행된다
또한, useEffect()함수가 컴포넌트 내부에서 선언되었기 때문에 컴포넌트의 props, state에 접근 가능하다


useEffect()함수가 언제 componentWillUnmount 기능 수행하는 지

import React, {useState, useEffect } from "react";

function UserStatus(props) {
  const [isOnline, setisOnline] = useState(null);
 
function handleStatusChange(status) {
	setIsOnline(status.isOnline);
}
 
useEffect(() => {
	ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
  	return () => {
      // 컴포넌트가 unmount될 때 호출됨!
      ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
    };
};

if(isOnline === null){
  return '대기 중...';
}
return isOnline ? '온라인' : '오프라인';     

하나의 component가 여러개의 useEffect() 사용

function UserStatusWithCounter(props) {
  const [isOnline, setisOnline] = useState(0);
  useEffect(() => {
    document.title = `${count}번 클릭했습니다.`;
  });
 
function handleStatusChange(status) {
	setIsOnline(status.isOnline);
}
 
useEffect(() => {
	ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
  	return () => {
      // 컴포넌트가 unmount될 때 호출됨!
      ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
    };
};

if(isOnline === null){
  return '대기 중...';
}
return isOnline ? '온라인' : '오프라인';     

총정리

useEffect(() => {
  	// 컴포넌트가 마운트 된 이후,
  	// 의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
  	// 의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행됨
  	// 의존성 배열 생략 시 컴포넌트 업에이트 시미다 실행됨
	...  
  
  return () => {
   	// 컴포넌트가 마운트 해제되기 전에 실행됨
  	...
  }
 
}, [의존성 변수1, 의존성 변수2, ...]);
profile
페라리 타는 백엔드 개발자

0개의 댓글