[React] 상태 유지 컴포넌트(stateful components) vs 무상태 컴포넌트(Stateless components)

summereuna🐥·2023년 3월 14일
0

React JS

목록 보기
31/69
import Card from "../UI/Card";
import "./Expenses.css";
import ExpenseItem from "./ExpenseItem";
import ExpensesFilter from "./ExpensesFilter";
import { useState } from "react";

const Expenses = (props) => {
  const [filteredYear, setFilteredYear] = useState("2020");

  const filterChangedYearHandler = (selectedYear) => {
    console.log("Expenses.js");
    console.log("selectedYear", selectedYear);
    setFilteredYear(selectedYear);
  };

  console.log("filteredYear", filteredYear);

  return (
    <Card className="expenses">
      <ExpensesFilter
        onChangeFilterYear={filterChangedYearHandler}
        //🔥양방향 바인딩: state select value로 넣기 위해 props으로 보내기
        selected={filteredYear}
      />
      <ExpenseItem
        id={props.items[0].id}
        title={props.items[0].title}
        amount={props.items[0].amount}
        date={props.items[0].date}
      />
      <ExpenseItem
        id={props.items[1].id}
        title={props.items[1].title}
        amount={props.items[1].amount}
        date={props.items[1].date}
      />
      <ExpenseItem
        id={props.items[2].id}
        title={props.items[2].title}
        amount={props.items[2].amount}
        date={props.items[2].date}
      />
      <ExpenseItem
        id={props.items[3].id}
        title={props.items[3].title}
        amount={props.items[3].amount}
        date={props.items[3].date}
      />
    </Card>
  );
};

export default Expenses;

양방형 바인딩을 사용할 때 마다 제어된 컴포넌트(Controlled Component) 라고 표현한다. 여기서는 사용자 지정 컴포넌트인 <ExpensesFilter /> 를 컨트롤(제어)하고 있다.
ExpensesFilter에서 드롭 다운으로 선택된 값이 props인 selected를 통해 부모 컴포넌트인 <Expenses /> 전달되어 부모 컴포넌트에 state로 저장되고, 또 다시 부모 컴포넌트로부터 state 값인 filteredYear를 값으로 받는다. 즉, 양방향 바인딩을 하면 자식 컴포넌트는 부모 컴포넌트로부터 제어된 컴포넌트가 된다.

부모와 자식 컴포넌트 모두에서 value를 설정하고 선택된 값을 다루는 함수를 사용한다. 하지만 이 값은 자식 컴포넌트인 <ExpensesFilter />에 속한 것이 아니라 부모 컴포넌트인 <Expenses />에 속한 값이다. 자식인 <ExpensesFilter /> 컴포넌트는 단지 UI를 나타내는 컴포넌트로 드롭다운을 보여줄 뿐, 실제 로직은 부모 컴포넌트인 <Expenses />가 가지고 있다.

이런 이유로 자식인 <ExpensesFilter /> 컴포넌트를 제어된 컴포넌트(Controlled Component)라고 한다. 값과 변경되는 값은 이 컴포넌트 자체에서 다루지 않고, 부모 컴포넌트에서 처리된다.
<Expenses /> 컴포넌트가 <ExpensesFilter /> 컴포넌트를 제어하는 것이다.

상태 유지 컴포넌트(stateful components) vs 무상태 컴포넌트(Stateless components)

1. 상태 유지 컴포넌트(Stateful Component, a.k.a. smart Component)

구축하는 모든 리액트 앱에는 일부 상태를 관리하는 몇개의 컴포넌트를 가지게 된다.

  • 이 filter의 state를 관리하는 Expenses 컴포넌트
  • 유저가 입력한 input state를 관리하는 ExpensesForm 컴포넌트

2. 무상태 컴포넌트(Stateless Component, a.k.a. Presentational or Dumb Component)

또 다른 컴포넌트로는, state를 관리하고 있지 않은 컴포넌트가 있다.
이 컴포넌트는 아무 상태를 갖지 않고 단지 데이터를 출력하는 UI를 위해 존재한다.
대부분의 리액트 프로그램에서 상태유지 컴포넌트 보다 더 많은 무상태 컴포넌트를 가지게 된다.
왜냐하면 재사용 가능한 작은 조각으로 컴포넌트를 쪼개기 때문에 대부분의 컴포넌트는 실제로 뭔가 출력하는데 초점을 맞추고 있기 때문이다.

아주 일부 컴포넌트만 state를 관리한다. 그리고 state는 결국 props를 통해 분산된다. filter의 상태를 관리하는 이 Expenses 컴포넌트에서 처럼말이다. filteredYear를 전달하고, 이 상태 값은 props를 통해 ExpensesFilter로 돌아온다.
이는 흔히 보이는 일반적인 패턴인데, state와 몇몇 컴포넌트를 관리하고 다른 컴포넌트로 state를 전달할 수 있다.

profile
Always have hope🍀 & constant passion🔥

0개의 댓글