무브라더

[React] State Hook 본문

Programming/React

[React] State Hook

동스다
반응형
SMALL

* React 공식 홈페이지 글을 발췌하였습니다.

 

Hook은 React 16.8에 새로 추가된 기능이며 함수형 컴포넌트에서도 상태 관리를 할 수 있는 useState, 그리고 렌더링 직후 작업을 설정하는 useEffect 등의 기능 등을 제공하여 기존의 함수형 컴포넌트에서 할 수 없었던 다양한 작업을 할 수 있게 해준다.

 

Hook 은 클래스형 컴포넌트에서는 동작하지 않는다. React 는 useState 같은 내장 Hook을 몇가지 제공하며 컴포넌트 간에 상태 관련 로직을 재사용하기 위해 직접 Hook을 만드는 것도 가능하다.

 

오늘은 State Hook에 대해서 정리해볼 것이다.

 

State Hook

 

import React, { useState } from 'react';

function Example() {
  // "count"라는 새 상태 변수를 선언
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

코드에서 useState가 바로 Hook 이다. Hook을 호출해 함수 컴포넌트 안에 state를 추가했고 이 state는 컴포넌트가 다시 렌더링 되어도 그대로 유지가 될 것이다.

useState 는 현재의 state 값과 이 값을 업데이트 하는 함수를 한 쌍으로 제공한다. 이 함 수를 이벤트 핸들러나 다른 곳에서 호출 할 수 있으며 이것은 class의 this.setState와 거의 유사하지만 이전 state 와 새로운 state를 합치지 않는다는 차이점이 있다.

 

useState 는 인자로 초기 state 값을 하나 받는다. this.state 와 달리 useState Hook 의 state는 객체일 필요가 없다.

원한다면 객체로도 사용이 가능하며 원시값을 사용 할 수도 있다.

 

이 초기값은 첫번째 렌더링에만 딱 한번 사용이 된다.

 

function ExampleWithManyStates() {
  // 상태 변수를 여러 개 선언
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  // ...
}

하나의 컴포넌트 내에서 State Hook을 여러 개 사용할 수도 있다.

구조분해할당 문법은 useState로 호출된 state 변수들을 다른 변수명으로 할당할 수 있게 해준다.

 

위 코드는 age, fruit, todos 라는 지역 변수를 가지며 개별적으로 갱신 할 수 있다.

function handleOrangeClick() {
    // this.setState({ fruit: 'orange' })와 같은 효과
    setFruit('orange');
}

여러 개의 state 변수를 사용하지 않아도 되며 state 변수는 객체와 배열을 가지고 있을 수 있기 때문에 서로 연관있는 데이터를 묵을 수도 있다. 하지만 클래스 컴포넌트의 this.setState 와 달리 state 를 갱신하는 것은 병합하는 것이 아니라 대체 하는 것이라는 걸 알고 있어야한다.

 

state 변수 선언하기

클래스 컴포넌트를 사용할 때는 constructor 안에서 this.state 를 {count : 0} 으로 설정함으로써 count 를 0으로 초기화 했다.

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
 }

클래스 컴포넌트와 달리 함수 컴포넌트는 this 를 가질 수 없기 때문에 this.state 를 할당하거니 읽을수는 없지만

useState Hook 을 직접 컴포넌트에 호출하여 사용할 수 있다.

import React, { useState } from 'react';

function Example() {
  // 새로운 state 변수를 선언하고 이것을 count 라고 부른다.
  const [count, setCount] = useState(0);

그럼 대체 useState를 호출한다는 것은 무엇을 의미하는걸까? 그건 바로 state 변수를 선언할 수 있다는 의미다.

위 코드에서 선언한 변수는 count 라고 부르지만 dsfjosdfjiwjefoewf 이렇게 아무 의미 없는 단어를 집어넣어도 된다.

useState 는 클래스 컴포넌트의 this.state 가 제공하는 기능과 똑같다. 일반적으로 일반 변수는 함수가 끝날 때 사라지지만 state 변수는 React에 의해 사라지지 않는다.

 

그럼 useState의 인자로 무엇을 넘겨줘야할까? useState() Hook 의 인자로 넘겨주는 값은 state의 초기 값이다.

함수 컴포넌트의 state는 클래스 컴포넌트와 달리 객체일 필요도 없고 원시객체를 가질 수도 있다 (숫자,문자,불리언 ... )

그런데 useState는 한개의 변수만 저장이 가능하므로 2개의 다른 변수를 저장하기 원한다면 useState를 두번 호출해야한다.

 

그럼 useState 는 무엇을 반환할까? state 변수, 해당 변수를 갱신할 수 있는 함수 두가지 쌍을 반환한다.

이것이 바로 ' const [count , setCount] = useState() ' 라고 사용하는 이유이다.

클래스 컴포넌트의 this.state.count 와 this.setState 와 유사하다.

 

state 가져오기

클래스 컴포넌트는 count를 보여주기 위해 this.state.count 를 사용한다.

<p>You clicked {this.state.count} times</p>

함수 컴포넌트는 count를 직접 사용할 수 있다.

<p>You clicked {count} times</p>

 

state 갱신하기

클래스 컴포넌트는 count 를 갱신하기 위해 this.setState()를 호출한다.

 <button onClick={() => this.setState({ count: this.state.count + 1 })}>
    Click me
 </button>

함수형 컴포넌트는 setCount 와 count 변수를 가지고 있으므로 this를 호출하지 않아도 된다.

<button onClick={() => setCount(count + 1)}>
    Click me
</button>

 

요약

import React, { useState } from 'react';
 
 function Example() {
    const [count, setCount] = useState(0);
    
    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
         Click me
        </button>
      </div>
    );
}

1. 첫번째 줄에서 useState Hook 을 React 에서 가져온다.

2. 네번째 줄에서 useState Hook 을 이용하면 state 변수와 해당 state를 갱신할 수 있는 함수가 만들어진다. 또한 useSate의 인자 값으로 0을 넘겨주면 count 값을 0으로 초기화 할 수 있다.

3. 아홉번째 줄에서 사용자가 버튼을 클릭하면 setCount 함수를 호출하여 state 변수를 갱신한다. React 는 새로운 count 변수를 Example 컴포넌트에 넘기며 해당 컴포넌트를 리렌더링한다.

 

* 대괄호의 의미 [] 

  const [fruit, setFruit] = useState('banana');

useState를 이용하여 변수를 선언하면 2개의 아이템 쌍이 들어있는 배열로 만들어진다.

첫번째 아이템은 현재 변수를 의미하고 두번째 아이템은 해당 변수를 갱신해주는 함수이다.

  var fruitStateVariable = useState('banana'); // 두 개의 아이템이 있는 쌍을 반환
  var fruit = fruitStateVariable[0]; // 첫 번째 아이템
  var setFruit = fruitStateVariable[1]; // 두 번째 아이템

이 코드는 위 코드를 분해한 코드다. [0] 이나 [1] 로 배열에 접근하는 것은 좋지 않다.

반응형
LIST
Comments