[React #10] React Hooks로 함수형, state 효율적으로 쓰기(feat.useState())

Kayoung Kim·2022년 1월 3일
0

React

목록 보기
10/15
post-thumbnail

Hooks 개발 배경

React의 Class형 컴포넌트로 모든 프로그래밍을 하던 시절, 개발자들은 React팀에 다음과 같은 feedback을 던진다.

  • "Class형은 컴포넌트 간 재사용하기 어려워요!"
  • "Class형은 복잡하고 테스트하는데 시간을 많이 잡아먹어요!"
  • "Class형은 많은 개발자들이 혼란을 겪고, 버그도 엄청 많이 나와요!"
    => 이러한 피드백을 반영해 React팀은 React 16.8+ 버전에서 'Hooks'을 선보였다.
    Hooks의 등장으로 간단한 함수형 컴포넌트만으로 클래스형 컴포넌트로만 할 수 있었던 온갖 아름다운 동작들을 구현할 수 있게 되었다!

Hooks

React Hooks는 함수에서 컴포넌트의 내부 states와 post-rendering side effetcts를 관리할 수 있게 해주었다.

  • Hooks는 클래스 안에서는 작동하지 않는다. 함수형 컴포넌트와 hooks는 클래스 컴포넌트의 대체제가 아니라, "선택사항"이다.
  • React는 내장 hooks 기능을 제공한다. useState(), useEffect(), useContext(), useReducer(), useRef()...
    full list

The State Hook - useState()

  • 함수형 컴포넌트의 state를 업데이트할 때 쓰는 hook으로 react component를 구성하기 위해 가장 흔하게 사용하는 hook이다.
  • useState를 react 라이브러리에서 import 한다.
    import React, {useState} from 'react';
  • useState()는 react 내부의 JavaScript 함수 정의로, 두 가지의 값을 갖는 배열로 리턴된다.
    const [current state, state setter] = useState();
    - current state : this state의 현재 값
    - state setter: this state 값이 업데이트 되어서 사용할 수 있는 함수
import React, {useState} from "react";

function Toggle() {
  const [toggle, setToggle] = useState();
  
  return (
    <div>
      <p>The toggle is {toggle}</p>
	  <button onClick={() => setToggle("on")}>On</button>
	  <button onClick={() => setToggle("off")}>Off</button>
    </div>
   );
}
  • setToggle()onClick 이벤트 리스너로 호출된다.
  • toggle값과 컴포넌트를 새로운 값으로 재렌더링하기 위해서는 setToggle() 함수를 다음 스테이트 값과 함께 argument처럼 호출해주기만 하면 된다.
    (class 인스턴스로 함수를 바인딩하고, constructor를 쓰고, this 키워드를 쓰고.. 따위는 신경쓰지 않아도 된다! 그저 State Hook으로 간단하게 스테이트를 업데이트 할 수 있게 된 것!🤭)

    React에 state setter 신호를 호출한다는 것은 컴포넌트의 재렌더링(re-render)과 이에 따라 컴포넌트 정의에 따른 전체 함수가 다시 호출되어야한다는 것을 의미한다.
    useState를 쓰면 React 컴포넌트에서 다른 부분으로 넘어갈 때 현재 스테이트의 값을 계속 추적할 수 있다.

State 초기화

  • State Hook으로 stiring을 포함한 원시 데이터 타입, 배열, 객체까지 관리할 수 있다.
  • state를 초기화하기 위해서는 useState() 함수 호출에 초기값을 argument로 전달해준다.
    const [isLoading, setIsLoading] = useState(true);
    1) 첫번째 렌더링에서 초기값이 사용된다.
    2) 두번째 state setter(setIsLoading)가 호출되면 React는 초기값을 무시하고, 새로운 값을 사용한다.
    3) 컴포넌트가 재렌더링되면, React는 이전 렌더링에 사용했던 값을 계속 사용한다.

    초기값을 설정하지 않으면 undefined가 뜬다. 동작하는데는 문제가 없으나 코드를 명확하게 하기 위해서는 명시해주는 것이 좋다. 만약 첫 렌더링에서 보여줄 값이 없으면 null처리를 해주는 것이 좋다.

JSX 외부에서 State setter 사용하기

  • 이벤트 핸들러를 붙여줄 때 해당 로직을 분리해주면 가독성 높고 효율적인 코드를 작성할 수 있다.
const handleChange = (event) => {
  const newEmail = event.target.value;
  setEmail(newEmail);
}

=> const handleChange = (event) => setEmail(event.target.value);

//Object destructing
=> const handleChange = ({target}) => setEmail(target.value);

이전 state로부터 setting 하기

  • 다음에 나올 state 값이 현재 state에서 계산이 되어야 하는 경우가 있다.
    이때, 가장 좋은 방법은 콜백 함수를 지정해 두는 것이다.
import React, { useState } from 'react';

export default function QuizNavBar({ questions }) {
  const [questionIndex, setQuestionIndex] = useState(0);

  // define event handlers 
  const goBack = () => setQuestionIndex((prevQuestionIndex) => prevQuestionIndex - 1);
  const goToNext = () => setQuestionIndex((prevQuestionIndex) => prevQuestionIndex + 1);
  // determine if on the first question or not 
  const onFirstQuestion = questionIndex === 0;
  const onLastQuestion = questionIndex === questions.length - 1;

  return (
    <nav>
      <span>Question #{questionIndex + 1}</span>
      <div>
        <button onClick={goBack} disabled={onFirstQuestion}>
          Go Back
        </button>
        <button onClick={goToNext} disabled={onLastQuestion}>
          Next Question
        </button>
      </div>
    </nav>
  );
}

0개의 댓글