React 다루기 4 - useState

손연주·2021년 6월 8일
0
post-custom-banner

useState를 통해 컴포넌트에서 바뀌는 값 관리하기

지금까지 리액트 컴포넌트를 만들어오면서 동적인 부분(값이 바뀌는 것)은 하나도 없었다. 이번에는 컴포넌트에서 보여줘야 하는 내용이 사용자 interaction에 따라 바뀌어야 할 때 어떻게 구현할 수 있는지에 대해 알아보자.

1. Hooks?

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

2. useState

: 가장 기본적인 Hook 으로서, 함수형 컴포넌트에서도 가변적인 상태를 지니고 있을 수 있게 해준다. 만약에 함수형 컴포넌트에서 상태를 관리해야 되는 일이 발생한다면 이 Hook 을 사용하면 된다.

어떻게 동적인 부분을 구현할 수 있을까?

1. 컴포넌트 설정

버튼을 누르면 숫자가 바뀌는 컴포넌트를 만들어보자

Counter.js

import React from 'react';

function Counter() {
  return (
    <div>
      <h1>0</h1>
      <button>+1</button>
      <button>-1</button>
    </div>
  );
}

export default Counter;

그 다음 App 에서 Counter 렌더링

App.js

import React from 'react';
import Counter from './Counter';

function App() {
  return (
    <Counter />
  );
}

export default App;

2. 이벤트 설정

버튼이 클릭 되었을 때 특정 함수를 호출하는 이벤트를 만들어보자

1) 카운트 컴포넌트 안에 필요한 함수 작성

2) button의 onClick 으로 각 함수를 연결

리액트에서 엘리먼트에 이벤트를 설정해줄 때에는 on이벤트이름={실행하고 싶은 함수} 형태로 설정한다. 여기서 주의해야 할 점은, 함수 형태를 넣어주어야 하지 함수를 호출해선 안된다. 함수를 <button onClick={onIncrease()}>+1</button> 이렇게 실행해주게 되면 리액트 컴포넌트가 렌더링되는 시점에서 함수가 호출되어버리기 때문이다.
이벤트를 설정할때에는 함수타입의 값을 넣어주어야 한다.

Counter.js

import React from 'react';

function Counter() {
  const onIncrease = () => {
    console.log('+1')
  }
  const onDecrease = () => {
    console.log('-1');
  }
  return (
    <div>
      <h1>0</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

3. 동적인 값 끼얹기, useState

컴포넌트에서 동적인 값을 상태(state)라고 부른다. 리액트에 useState라는 함수를 사용해 컴포넌트에서 상태를 관리해보자.

Counter.js

import React, { useState } from 'react'; 

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber(number + 1);
  }

  const onDecrease = () => {
    setNumber(number - 1);
  }

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;
import React, { useState } from 'react'; 

1) 이 코드는 리액트 패키지에서 useState 라는 함수를 불러와준다

const [number, setNumber] = useState(0);
//number라는 상태를 만들 건데 number의 상태 기본값은 0으로 하고, 
//setNumber(현재 상태를 업데이트하는 함수) 함수를 이용해서 그 상태를 바꿔주겠다.

배열 비구조화 할당을 통하여 각 원소를 추출, useState를 사용할 때에는 상태의 기본값을 파라미터로 넣어서 호출해준다. 이 함수를 호출하면 배열이 반환되는데, 첫번째 원소는 현재 상태, 두번째 원소는 Setter 함수이다.

2) Setter 함수는 파라미터로 전달 받은 값을 최신 상태로 설정해준다

const onIncrease = () => {
    setNumber(number + 1);
  }

  const onDecrease = () => {
    setNumber(number - 1);
  }

그리고 h1 태그에서는 이제 0이 아닌 {number}값을 보여줘야 한다.

<h1>{number}</h1>

함수형 업데이트?

Setter 함수를 사용 할 때 업데이트 하고 싶은 새로운 값을 파라미터로 넣어주고 있는데, 그 대신에 기존 값을 어떻게 업데이트 할 지에 대한 함수를 등록하는 방식으로도 값을 업데이트 할 수 있다.

Counter.js

import React, { useState } from 'react';

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber(prevNumber => prevNumber + 1);
  }

  const onDecrease = () => {
    setNumber(prevNumber => prevNumber - 1);
  }

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

onIncrease 와 onDecrease 에서 setNumber 를 사용 할 때 그 다음 상태를 파라미터로 넣어준것이 아니라, 값을 업데이트 하는 함수를 파라미터로 넣어주었다. 함수형 업데이트는 주로 나중에 컴포넌트를 최적화를 하게 될 때 사용하게 된다.

참고

Q. prevNumber는 선언한적이 없는데 어디서 나타난 건가?
A. useState 함수를 개발한 개발자가 정한 것, 콜백함수 개념을 알고 있으면 이해하기 쉽다.

const [state, setState] = useState();

setState란 함수에 파라미터로 함수를 넘겨주면, 콜백함수의 파라미터에 이전 state 값을 넣어준다.

const [number, setNumber] = useState(0);
// setState 함수는 setNumber함수로 설정되어 있음

const onIncrease = () => {
  setNumber(prevNumber => prevNumber + 1); 
  //setNumber 함수 파라미터에 또 함수가 들어가면
  //인자 prevNumber는 이전 state 값을 넣어준다
}

이 식은

function onIncrease() {
    return setNumber(function(prevNumber){
         return prevNumber + 1 //콜백함수
 	});
  }

이 식과 같다. 여기서 콜백함수 파라미터인 prevNumber는 이전에 있는 스테이츠 값과 같다.

profile
할 수 있다는 생각이 정말 나를 할 수 있게 만들어준다.
post-custom-banner

2개의 댓글

comment-user-thumbnail
2021년 6월 8일

useState... React에서 인정했다 이 말이거든요 ~

1개의 답글