본문 바로가기

FRONTEND

[React] Learning React Chapter 6 - 상태 관리

해당 글은 'Learning React 러닝 리액트 2판(한빛미디어 출판)에 대한 내용을 바탕으로 개인 학습 목적을 위해 작성되었습니다. 잘못된 내용이 있을 수 있으니 참고 부탁드리며 해당 내용에 대해 피드백주시면 반영할 수 있도록 하겠습니다.

 

 

React를 다루면서 프로퍼티 만큼이나 상태(state)에 대해 많이 접하게 됩니다. 프로퍼티를 통해 상태를 다른 컴포넌트에 전달하는 연결통로 라고 한다면 상태는 실제로 우리가 화면에서 볼 수 있는 어떠한 데이터 및 값이라고 할 수 있습니다. 이번 챕터에서는 이 상태를 관리하는 방법과 상태를 다른 컴포넌트로 전달하는 방법 및 상태를 효율적으로 관리하는 방법 등에 대해 알아보겠습니다.

 

별점 컴포넌트를 만드는 것으로 시작해보겠습니다.

 

우선 react-icons 를 사용하여 Star 컴포넌트를 만들겠습니다. 아래와 같이 Star 컴포넌트는 selected, onSelect 프로퍼티를 갖고 선택 여부와 클릭 여부에 따라 색상이 변경됩니다.

// ./src/components/Star.js

import { FaStar } from "react-icons/fa";

const Star = ({ selected = false, onSelect = (f) => f }) => {
  return <FaStar color={selected ? "red" : "grey"} onClick={onSelect} />;
};

export default Star;

 

Star 컴포넌트를 활용하여 Starating 컴포넌트를 만들어보겠습니다.

 // ./src/components/StarRating.js

import { useState } from "react";
import Star from "./Star";
import { createArray } from "../utils/lib";

const StarRating = ({ style = {}, totalStars = 5, ...props }) => {
  const [selectedStars, setSelectedStars] = useState(0);

  return (
    <div style={{ padding: 5, ...style }} {...props}>
      {createArray(totalStars).map((n, i) => (
        <Star
          key={i}
          selected={selectedStars > i}
          onSelect={() => {
            setSelectedStars(i + 1);
          }}
        />
      ))}
      <p>
        {selectedStars} of {totalStars} Stars
      </p>
    </div>
  );
};

export default StarRating;



// ./src/utils/StarRating.js

export const createArray = (length) => [...Array(length)];

StarRating 컴포넌트는 useState 훅을 사용하고 있습니다. 여기서 훅이란, 해당 컴포넌트와 엮는다라는 의미로 이해할 수 있습니다. React에서 제공하는 훅의 종류는 여러가지인데 그 중에 useState 훅은 상태와 그 상태를 업데이트 하는 함수를 담은 배열을 반환하는 훅입니다. 위에서는 selectedStars, setSelecetedStars가 각각 이에 해당합니다. 또한 여기에서 중요한 것은 훅이 사용되는 컴포넌트를 렌더러와 연결시킨다는 점 입니다. 위 예제에서 setSelecetedStars를 이용하여 selectedStars의 상태를 변경한다면 변경된 상태를 반영하여 새롭게 렌더링 된다는 뜻입니다. 즉, 훅이 걸려있는 컴포넌트의 상태가 변경이 된다면 해당 컴포넌트에서 리렌더링이 발생하여 변경된 상태를 반영한 화면을 볼 수 있게 됩니다.

 

또 StarRating 컴포넌트는 selected, onSelect 프로퍼티를 Star 컴포넌트에 전달하는 것을 확인할 수 있습니다. 이렇듯 부모인 StarRating 컴포넌트에서 자식인 Star 컴포넌트로 상태를 넘겨주는 상태 전달방식을 확인할 수 있습니다.

 

별 아이콘을 클릭하게되면 selectedStars 상태가 1씩 증가하고 slected의 값이 true가 되기 때문에 별의 색상이 붉은색으로 업데이트 되는 것을 확인할 수 있습니다.

 

위 예제를 실행하면 다음과 같은 화면을 볼 수 있습니다.

 

이렇게 컴포넌트 내부에서 상태를 useState를 사용하여 관리하고 props를 통해 전달해주는 방식을 살펴보았습니다. 하지만 위 예제와는 달리 관리해야할 상태가 많아질 경우, 컴포넌트 내부에서 상태를 관리하고 상태가 컴포넌트 이곳 저곳에 분산된다면 버그 추적, 애플리케이션의 기능을 변경하기가 어려워집니다. 또한 같이 개발을 해나가는 과정에서 코드의 흐름을 이해하는데 방해요소가 되기도 합니다. 이에 대한 해결책으로 상태를 한 곳에서 관리하는 방법이 있습니다. 이 중  첫번째는 상태를 컴포넌트 트리(트리의 최상위인 App.js)에 저장하고 자식 컴포넌트에게 props를 통해 전달하는 방식입니다.