[React] Stateless 컴포넌트와 Stateful 컴포넌트

SuamKang·2023년 6월 20일
0

React

목록 보기
12/34
post-thumbnail

✔️ 컴포넌트를 제어한다는건 무슨말일까?


const ExpensesFilter = (props) => {
  
  const getValueHandler = (event) => {
    // 부모컴포넌트인 Expenses컴포넌트로 부터 받은 props 이벤트 함수
    // 해당 함수 안의 로직은 부모컴포넌트에서 props.onChangeFiltered에 접근하여 작업이 이루어지고 getValueHandlerg함수는 단지 props함수의 호출을 해주는 역할만 할 뿐,
    // 상태를 직접적으로 업데이트하는 역할은 아니다는 것!
    props.onChangeFiltered(event.target.value);
  };

  return (
    <div className="expenses-filter">
      <div className="expenses-filter__control">
        <label>Filter by year</label>
        <select value={props.filteredYear} onChange={getValueHandler}>
          <option value="2022">2022</option>
          <option value="2021">2021</option>
          <option value="2020">2020</option>
          <option value="2019">2019</option>
        </select>
      </div>
    </div>
  );
};

export default ExpensesFilter;

컴포넌트에서 사용되는 값은 예를들어 위 예시에서 드롭다운에서 선택된 값으로 볼 수 있고, 이는 props를 통해 부모 컴포넌트에 전달되어 상태가 업데이트 되고, 양방향 바인딩을 통해 다시 부모로부터 props로 전달 받은 값인 것이다.

위 코드에서 select요소 안에 value와 onChange 속성값은 모두 해당 컴포넌트의 한 부분이 아닌 부모로 부터 받은 props 에 접근된 값들이다.

쉽게말해 ExpensesFilter는 UI를 나타내는 컴포넌트이며 드롭다운을 보여주고 있다. 또한 리스너나 props를 갖고 있는 형태이다.


하지만 실제 상태를 업데이트해주는 로직은 부모인 Expenses.js가 가지고 있는것이다.
이를 통해서 ExpensesFilter컴포넌트를 제어된 컴포넌트로 바꿀 수 있다.

이렇게 어떤 부모(상위)컴포넌트의 상태를(값 또는 함수) 접근해서 적용해 쓰는 자식(하위) 컴포넌트는 부모 컴포넌트의 제어를 받고 있다고 볼 수 있다.



✔️ Stateless, Stateful 컴포넌트


모든 리엑트 앱에는
일부 상태를 관리하는 몇 개의 컴포넌트를 갖게 되고

ex)

Expenses컴포넌트 안 filteredYear state

function Expenses(props) {
  const [filteredYear, setFilteredYear] = useState("2021");

  const filterHandler = (selectedYear) => {
    setFilteredYear(selectedYear);
  };

  return (
    <div>
      <Card className="expenses">
        <ExpensesFilter
          filteredYear={filteredYear}
          onChangeFiltered={filterHandler}
        />
        {props.expenses.map((item, index) => {
          return (
            <ExpenseItem
              key={index}
              date={item.date}
              title={item.title}
              amount={item.amount}
            />
          );
        })}
      </Card>
    </div>
  );
}

export default Expenses;

ExpensesForm컴포넌트 안 input state들

function ExpenseForm(props) {
  const [enteredTitle, setEnteredTitle] = useState("");
  const [enteredAmount, setEnteredAmount] = useState("");
  const [enteredDate, setEnteredDate] = useState("");
  
  (생략)
  
  }

그렇지 않고 상태를 관리하진 않는 컴포넌트가 있는데

ex)

ExpenseItem컴포넌트

function ExpenseItem(props) {
  return (
    <Card className="expense-item">
      <ExpenseDate date={props.date} />
      <div className="expense-item__description">
        <h2>{props.title}</h2>
        <div className="expense-item__price">${props.amount}</div>
      </div>
    </Card>
  );
}

export default ExpenseItem;

이는 무상태 컴포넌트 라고 부른다. (stateless컴포넌트 or 프리젠테이셔널 or dumb컴포넌트 등등으로 불린다)

이 컴포넌트들은 단지 데이터를 출력하기 위해 존재하는 것 뿐이다.

리엑트 개발시 보통은
상태유지 컴포넌트보다 무상태 컴포넌트들이 더 많아진다.

Stateless >>> Stateful

그 이유는 컴포넌트 개발로 진행하면서 더 작은단위로 쪼개어 재사용 가능한 부분으로 만들고 싶은건데 그러한 컴포넌트 조각들은 실제로 무언가를 출력하는데 초점을 맞추고 있고, 결국 렌더링을 해서 사용자가 볼 수 있도록 구성을 해야하기 때문이다.


따라서,
그 몇몇 상태를 유지하고 있는 컴포넌트(smart컴포넌트)에서 해당 상태를 props를 통해 분산시키게 되는것이다.

profile
마라토너같은 개발자가 되어보자

0개의 댓글