Skip to content

Instantly share code, notes, and snippets.

@ninanung

ninanung/ReactHooks1.md

Last active May 17, 2020
Embed
What would you like to do?
때늦은 React Hooks 시리즈 1탄 - 개요/useState

이 글의 코드는 저자의 Github에서 확인할 수 있습니다.

때늦은 React Hooks 시리즈 1탄 - 개요/useState

나온지가 언제인데 지금에서야 이걸...?

그건 제가 이제서야 이걸 알았기 때문입니다. 늦게라도 알았으니 시작해야죠 별수 있나요.

개요

React Hooks는 작년인 2018년 10월 26일에 ReactConf 2018에서 발표되었습니다. 기존의 함수 방식의 컴포넌트에서는 state의 사용이 불가능하다는 단점을 보완하고, class기반 컴포넌트를 대체할 목적으로 만들어 졌습니다. class기반 컴포넌트를 대체한다? 잘 쓰고있던 class 컴포넌트에 무슨 문제가 있길래 그럴까요? React나 기타 비슷한 프레임워크의 큰 장점 중 하나는 컴포넌트의 재사용성입니다. 같은 HTML, JavaScript코드를 비슷한 기능을 위해 반복하여 작성하는게 아니라 하나의 컴포넌트로 만들어 재사용 한다는 개념입니다. 멋집니다! 허나 실상은 그렇게 간단하지만은 않았습니다. 어느정도의 코드들은 재사용이 가능하다고 하더라도, 하나의 컴포넌트 안에서 React lifecycle이나 UI를 위해 특정 함수를 여러번 사용해야 하는 문제가 있었습니다. 컴포넌트를 재사용 하기 위해 더 복잡한 길을 선택하는 모순이 생기는 겁니다. 사실 이건 관련 글을 읽기 전에 혼자 코딩을 할때도 느꼈던 점입니다만, 다른 사람들도 비슷한 생각을 했었나 봅니다. 어쨌든, 이런 문제를 해결하기 위해 HOC와 같은 방식도 사용해 봤지만 코드가 복잡해지는 것을 막을수는 없었습니다. 바로 이러한 문제점들을 해결하기 위해 제안된 것이 React Hooks입니다.

React Hooks에서 Hook이라는건 걸어낸다는 뜻입니다. 개발에 있어서 Webhook이니 하는 단어를 들어보셨을지 모르겠지만, 특정 동작/이벤트가 발생했을 때 특정 행동을 자동으로 실행하는 방식을 얘기합니다. React Hooks를 배워가다 보면 왜 그렇게 부르는지 이해가 갈 거라고 생각합니다. 우선은 예제를 보고 뭐가 다를지 느껴보도록 합시다. 자세한 설명은 뒤에 더 하겠습니다.

import React from 'react';

class Example extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            test: 'initial value',
        }
    }

    changeText = (e) => {
        this.setState({
            test: e.target.value,
        })
    }

    render() {
        return (
            <div>
                <p>{this.state.test}
                <input onChange={this.changeText} />
            </div>
    }
}

export default Example;

이 코드는 기존의 class방식 컴포넌트를 작성한 예입니다. input안의 값이 변할 때 마다 state를 변경합니다. 이걸 React Hooks를 이용하면 굉장히 간단하게 만들 수 있습니다.

import React, {useState} from 'react';

const Example = () => {
    const [test, setTest] = useState('initial value');

    return (
        <div>
            <p>{test}</p>
            <input onChange={(e) => {setTest(e.target.value)}} />
        </div>
    )
}

export default Example;

이 코드 역시 제가 평소에 작성하던 버릇 그대로 작성했지만, 알아볼 수 있을만큼 충분히 짧아졌죠? 심지어 class컴포넌트도 아니기 때문에 함수로의 활용성이 더 넓어졌습니다. 위의 코드에서 사용한 useState에 대해서 제대로 된 설명으로 들어가 보도록 하겠습니다.

useState

useState는 class컴포넌트의 this.statethis.setState를 합친것과 비슷한 느낌입니다. react모듈을 통해 import할 수 있으며, 함수 컴포넌트에서 state를 사용할 수 있게 해줄 뿐만 아니라 선언시의 두번째 인자를 통해 state의 변경도 구현할 수 있습니다. 위에서 사용했던 예제를 그대로 사용해 봅시다.

import React, {useEffect, useState, useMemo, useCallback, useRef, useReducer, useContext} from 'react';
import './App.css';

const UseStateExample = () => {
  const [test, setTest] = useState('initial value');

  return (
    <div>
      <p>{test}</p>
      <input onChange={(e) => {setTest(e.target.value)}} />
    </div>
  )
}

function App() {
  return (
    <div className="App">
      <UseStateExample />
    </div>
  );
}

export default App;

자 코드는 간단합니다. 함수 컴포넌트를 하나 만들었고, 기본이 되는 App컴포넌트에서 불러와 렌더링합니다. 위의 코드를 그대로 가져왔으니, 쉽게 예상할 수 있는 것 처럼 state의 변경에 따라 <p></p>테그에서 해당 값을 출력합니다. 유심히 봐야 할 부분은 state를 선언하는 부분입니다. 개요에서 this.statethis.setState를 합친것과 비슷하다고 한 것 처럼, testsetTest를 동시에 선언하여 state와 해당 state를 설정하는 변수를 동시에 할당합니다.

const [test, setTest] = useState('initial value')

또한 useState에서 매개변수를 사용하여 초기값을 설정할 수 있습니다. 해당 코드에서는 initial value라는 문자열로 초기값을 설정했습니다. 실제로 코드를 실행해 보면

test

위의 사진과 같이 input안의 값을 받아서 state를 변화시키는 걸 확인하실 수 있습니다.

다음 글에서는 useContextuseEffect를 알아보도록 하겠습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment