본문 바로가기

클라이언트/React
[리액트(React)] forwarded props(proxy props)

프로젝트의 볼륨이 커지다 보면, 같은 구조의 컴포넌트가 반복되는 경우가 생긴다.

<section id="examples">
    <h2>Examples</h2>
    <menu>
        <TabButton isSelected={selectedTopic === 'components'}
                    onSelect={() => handleSelect('components')}>
        Components
        </TabButton>
    </menu>
    {tabContent}
</section>


위와 같은 구조가 여러 컴포넌트에서 반복될 때, 아래와 같은 공통 컴포넌트를 추출할 수 있다.

export default function Section({ title, children }) {
  return (
    <section>
      <h2>{title}</h2>
      {children}
    </section>
  );
}


이제 새로 생성한 공통 컴포넌트를 사용한다.

<Section title="Examples" id="examples">
    <menu>
        <TabButton isSelected={selectedTopic === 'components'}
                    onSelect={() => handleSelect('components')}>
        Components
        </TabButton>
    </menu>
    {tabContent}
</Section>


그런데 이렇게 하면?

클래스 속성이 깨진다..!!!

css를 id로 정의해뒀는데, 섹션 컴포넌트에 id 속성을 지정되지 않았기 때문이다.

props는 커스텀 컴포넌트에 자동으로 적용되거나 해당 컴포넌트 속 JSX 코드로 넘어가지 않는다.

그렇다고 props를 하나하나 수동으로 구조 분해 할당하면 규모가 커질수록 비효율적이다.

이럴 때 props를 효율적으로 넘겨받아 적용하는 패턴이 바로 forwarded props(전달 속성) 또는 proxy props(대리 속성)이다.

해당 컴포넌트의 구조에 필수적으로 사용되는 props를 구조 분해하여 받은 후, 그 외의 props는 rest 연산자(...)를 사용해서 모두 다른 props를 props object로 병합한다.

export default function Section({ title, children, ...props }) {
  return (
    <section>
      <h2>{title}</h2>
      {children}
    </section>
  );
}


병합된 props를 컴포넌트의 built-in 속성 요소로 가져온다.
여기서의 ...은 rest 연산자가 아닌 spread 연산자!

export default function Section({ title, children, ...props }) {
  return (
    <section {...props}>
      <h2>{title}</h2>
      {children}
    </section>
  );
}

id도 props로 적용된 것 확인!