[React] Props

Nine·2022년 5월 8일
1

React

목록 보기
9/22

React에서의 상태

리액트 앱에서 컴포넌트의 상태를 다루는 방법은 크게 2가지 입니다.

  1. 변경할 수 있는 상태를 다루기
    • 컴포넌트 내에서 변경 가능한 데이터인 상태 (state)
  2. 변경할 수 없는 상태를 다루기
    • 컴포넌트가 변경할 수 없고, 읽기 전용으로 전달 받는 데이터인 속성 (props)
    • ❗ React에서는 props를 Object.freeze로 불변성을 가진 읽기 전용으로 다룹니다.

속성 (Props)

속성은 리액트 컴포넌트에 전달되는 데이터입니다.

  1. 보통 부모 컴포넌트가 전달합니다.

  2. 컴포넌트 자체의 defaultProps 정적 메서드를 통해 전달할 수도 있습니다. 👇

export default class Hello extends Component {
}

Hello.defaultProps = {
    name:"초기값"
}

속성(Props)은 왜 불변 데이터?

리액트 컴포넌트 내에서는 state를 직접 업데이트 해서는 안됩니다.

  1. setState가 state를 곧바로 갱신하는 것이 아니라 상태 전환을 pending 합니다. (비동기)

  2. setState() 메서드를 호출한 후에 직접 state에 접근하게 되면 갱신 되지 않은 기존의 값이 리턴될 가능성이 있어요.

  3. 이는 디버깅이 어려운 상태가 될 수 있기에 확실히 기존 데이터와는 다름을 알려주는 불변 데이터로 다뤄야 합니다.

(아래에서 조금 더 이야기 해봅시다.)


🤔 생각해보기

리액트에서 속성을 불변 객체로 다루는 이유는 무엇일까요?

얕은 비교

  • 리액트는 상태 변화로 View를 리렌더링합니다.

  • 그 과정에서 얕은 비교를 수행합니다. (원시값은 바로 비교, 참조값은 참조하는 주소를 비교)

    • 👉 직접 객체의 값을 하나 하나 비교하는 것보다 변경 전후의 상태 트리를 빠르고 저렴하게 비교할 수 있죠.
  • 즉, 불변 객체로 다루면 주소값만으로도 변화를 감지할 수 있습니다.


하위 컴포넌트에서 상위 컴포넌트의 상태인 Props 를 직접 수정할 수 없는 이유는 무엇일까요?

React에서 props는 부모에서 자식으로 흐릅니다.

즉, React는 부모 노드를 렌더링하고 자식 노드에게 props을 전달하면 이제 부모 노드는 렌더링이 끝난 상태입니다.

그런데 만약 여기서 자식 노드가 props를 변경한다면 부모 노드는 다시 렌더링이 될 수 있을까요? → 이미 렌더링이 완료된 상태인데 불가능하겠죠.

이로 인해 이상한 동작이 발생할 수 있습니다.

(앱의 한 부분에 하나의 값이 있고 다른 부분에 다른 값이 있을 수 있으며 다음에 렌더링이 트리거 될 때 자체적으로 업데이트 될 수 있겠죠😢😢)


만약 양방향 수정을 지원한다고 하면 어떨까요?

데이터 전파.. 오래 걸려..

  • 하위 컴포넌트에서 Props를 직접 수정하면 양방향 바인딩이 되겠네요.

  • Angular 1에는 양방향 바인딩으로 언제 어디서나 모든 데이터를 변경할 수 있다고 해요.

  • 그러다보니 모든 데이터가 전파를 마칠 때까지 DOM을 다시 렌더링하여 주위를 돌아 다니는 작업을 반복합니다.

😢 결국 Angular 1이 너무 느려지게 되었어요.


Prop Drilling을 해결할 수 있는 방법은?

  1. Props Drilling을 해결하는 방법은 전역 상태 관리가 있어요.
 1. Context API, Redux 같은 State Container
 
 2. Store Management
  1. 또,children을 적극 활용하는 방법도 있습니다.

    👇 예시를 보실까요?

  • App에서 content를 가지고 있어요.
  • 가장 하위 자식인 ComponentNeedingProps 컴포넌트에 content를 넘겨주려면 어떻게 해야할까요?
import React from "react";
import "./styles.css";

export default function App() {
  const content = "Who needs me?";
 return (
    <div className="App">
      <FirstComponent>
        <SecondComponent>
          <ThirdComponent>
            <ComponentNeedingProps content={content}  />
          </ThirdComponent>
        </SecondComponent>
      </FirstComponent>
    </div>
  );
}

function FirstComponent({ children }) {
  return (
    <div>
      <h3>I am the first component</h3>;
     { children }
    </div>
  );
}

function SecondComponent({ children }) {
  return (
    <div>
      <h3>I am the second component</h3>;
     {children}
    </div>
  );
}

function ThirdComponent({ children }) {
  return (
    <div>
      <h3>I am the third component</h3>
        {children}
    </div>
  );
}

function ComponentNeedingProps({ content }) {
  return <h3>{content}</h3>
}
  • props로 자식에게 전달 전달하는 것은 우아하지 않죠.

  • 대신 이렇게 children을 적극 활용한다면 필요한 컴포넌트에서만 props로 content를 넘겨줄 수 있습니다.

profile
함께 웃어야 행복한 개발자 장호영입니다😃

0개의 댓글