DEVLOG

React Hooks에 대해 알아보자 (1) :: useState, useEffect 본문

frontend/react

React Hooks에 대해 알아보자 (1) :: useState, useEffect

meroriiDev 2021. 2. 9. 09:33
728x90
반응형

Hooks는 리액트 v16.8에 새로 도입된 기능으로 함수형 컴포넌트에서도 상태관리를 할 수 있는 useState, 렌더링 직후 작업을 설정하는 useEffect등의 기능을 제공하여 기존의 함수형 컴포넌트에서 할 수 없었던 다양한 작업을 할 수 있게 해준다!

 

  • useState
  • useEffect
  • useRef
  • useMemo
  • useCallback
  • useReducer
  • 커스텀 Hooks

○ useState

가장 기본적인 Hook이며 함수형 컴포넌트에서도 가변적인 상태를 지닐 수 있게 해준다.

리액트 16.8 이전 버전에서는 함수형 컴포넌트에서 state를 사용할 수 없었다. 16.8이후부터는 useState함수를 이용하여 함수형 컴포넌트에서도 state를 사용하여 가변적인상태를 지닐 수 있게 해준다.

따라서 함수형 컴포넌트에서 상태를 관리해야한다면 이 Hooks를 사용하면 되겠습니다~~

 

const [상태값, 상태함수] = useState(초기값);

 

+ 배열 비구조화 할당

Hooks를 사용하기 전에 배열 비구조화 할당에 대해 먼저 알아보자!

이전에 알고있던 객체 비구조화 할당과 비슷하다 즉, 배열안에 있는 값을 쉽게 추출할 수 있도록 해주는 문법이다!

const array = [1,2];
const one = array[0];
const two = array[1];

위와 같이 array안에 있는 값을 one과 two에 담아주는 코드를 배열 비구조화 할당을 사용하면 다음과 같이 표현할 수 있다.

 

const array = [1,2];
const [one, two] = array;

 

실습 :: 숫자 카운터

Counter.js

import React, {useState} from 'react';

const Counter = () =>{
    const [value, setValue] = useState(0);

    return(
        <div>
            <p>
                현재 카운터 값은 <b>{value}</b>입니다.
            </p>
            <button onClick={()=>setValue(value+1)}>+1</button>
            <button onClick={()=>setValue(value-1)}>-1</button>
        </div>
    )
}

export default Counter;

 

const [value, setValue] = useState(0);

useState함수의 파라미터에 0 이라는 상태의 기본값을 넣어준다. 이는 카운터의 기본값을 0으로 설정하여 준다는 뜻!

value의 값은 상태값이고 두번째 원소인 setValue는 상태를 설정하는 함수이다.

 

따라서 value라는 값에 초기값 0을 넣어 준비시키고

변화가 필요할때는 setValue를 사용하여 value의 값을 변화시켜주는 것 이다!

 

실습2 :: 여러개의 useState

Info.js

import React, {useState} from 'react';

const Info = () => {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');

    const onChangeName = (e) => {
        setName(e.target.value);
    }

    const onChangeNickname = (e) => {
        setNickname(e.target.value);
    }

    return(
        <div>
            <div>
                <input onChange={onChangeName} value={name}/>
                <input onChange={onChangeNickname} value={nickname}/>
            </div>
            <div>
                <div>이름 : {name}</div>
                <div>닉네임 : {nickname}</div>
            </div>
        </div>
    );
}

export default Info;

위와 같이 2개이상의 useState도 충분히 이용할 수 있다.

 

 

○ useEffect

useEffect는 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이다.

마운트(처음 나타났을때)/언마운트(사라질 때)/업데이트시(특정 props가 바뀔 때) 특정 작업을 처리할 수 있다.

클래스형 컴포넌트의 componentDidMout와 componentDidUpdate를 합친 형태라고 할 수 있다.

 

주로, 마운트 시에 하는 작업들은 다음과 같은 사항들이 있다.

  • props 로 받은 값을 컴포넌트의 로컬 상태로 설정
  • 외부 API 요청 (REST API 등)
  • 라이브러리 사용 (D3, Video.js 등...)
  • setInterval 을 통한 반복작업 혹은 setTimeout 을 통한 작업 예약

그리고 언마운트 시에 하는 작업들은 다음과 같은 사항이 있다.

  • setInterval, setTimeout 을 사용하여 등록한 작업들 clear 하기 (clearInterval, clearTimeout)
  • 라이브러리 인스턴스 제거

렌더링 될 때마다

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

const Info = () => {
    const [name, setName] = useState('');
    const [nickname, setNickname] = useState('');
    useEffect(()=>{
        console.log("렌더링이 완료되었습니다");
        console.log({name, nickname});
    });

	...

위에 사용한 Info.js에 useEffect를 추가해주었다.

렌더링이 될때마다 콘솔이 찍힌다! 빠르게 후다닥 치면 체크 못하려나 하고 빠르게도 쳐봤는데 바보같은 짓이었다.

마운팅될 때만(처음 나타났을 때)

useEffect(()=>{
	console.log("마운트될때만 실행합니다.");
	console.log({name, nickname});
},[]);

위 코드처럼 useEffect의 두번째 파라미터 deps에 비어있는 배열 []을 넣어주면 된다!

그러면 렌더링될때마다 콘솔이 찍히는게 아니라 화면에 처음 렌더링될 때만 실행이 된다.

특정 값이 업데이트될 때만

componentDidUpdate(prevProps, prevState) {
  if (prevProps.value !== this.props.value) {
    doSomething();  
  }
}

클래스형 컴포넌트라면 이렇게 작성을 할테야...... 이 코드를 useEffect를 사용해서 해야한다면?!

useEffect(()=>{
	console.log("마운트될때만 실행합니다.");
	console.log({name, nickname});
},[name]);

빈 배열로 비워두었던 deps에 변함을 감지할 변수명을 넣어주면된다!

이 배열 안에는 useState를 통해 관리하고 있는 상태를 넣어주어도 되고, props로 전달받은 값을 넣어주어도 된다!

 

그러면 위의 경우 name에 변화가 생길때만 렌더링이 진행이 된다!!

 

뒷정리하기(cleanup)

컴포넌트가 언마운트되기 전이나 업데이트 되기 직전에 어떠한 작업을 수행하고 싶다면

useEffect에서 뒷정리함수를 반환해주어야 한다!

useEffect(()=>{
  console.log("마운트될때만 실행합니다.");
  console.log({name, nickname});
  return()=>{
    console.log('cleanup~!');
    console.log(name);
  }
});

 

음.... 언마운트될때만 실행해주고싶었던건데 렌더링될때마다 실행되고있고,

뒷정리 함수가 호출될 때는 업데이트 되기 직전 name값을 출력해주고 있다.

사실 아무리 코드를 들여다봐도 언마운트될 때만 실행하라는 코드가 없긴 하다!

useEffect(()=>{
  console.log("마운트될때만 실행합니다.");
  console.log({name, nickname});
  return()=>{
    console.log('cleanup~!');
    console.log(name);
  }
},[]);

오직 언마운트될 때만(사라질때만) 뒷정리 함수를 호출하고 싶다면

useEffect함수 두번째 파라미터 deps를 비워주면 된다!

 

 


참고 velog.io/@velopert/react-hooks

728x90
반응형
Comments