[React] props, children

Jaehyun Park·2023년 10월 28일
post-thumbnail

react 교재로 공부를 하던 중 props도 뭔지 모르는 상태에서 children이 나와서 멘붕에 빠졌다...
구글링 결과 개념은 알 수 있었다. 작동 원리는 생략하고 어떻게 동작하는지 정리해봤다.


1. props (property)

props는 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하기 위해 사용하는 속성이다.

props는 부모 컴포넌트에서 자식 컴포넌트로 읽기 전용(read-only)으로 전달된다. 즉, 데이터를 읽기만 하고 상태 변경은 할 수 없으며 이 기능을 수행하기 위해서는 useState를 사용해야 한다.

자식 컴포넌트에서는 부모 컴포넌트로부터 전달받은 props를 통해 데이터를 사용할 수 있다.

클래스 컴포넌트로 작성된 다음 예제 코드를 보자.

// 자식 컴포넌트
import React from 'react';

class ChildComponent extends React.Component {
  render() {
    return (
      <div>{this.props.message}</div>
    );
  }
}
// 부모 컴포넌트
import React from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends React.Component {
  render() {
    const data = "Hello from parent!";
    return (
      <ChildComponent message={data} />
    );
  }
}
  1. 자식 컴포넌트(ChildComponent)에서 {this.props.message}를 통해 message라는 이름의 속성을 받겠다고 했다. 그럼 이 자식 컴포넌트를 참조하는 부모 컴포넌트에서 message라는 이름의 속성으로 값을 전달해줄 수 있게 된다.
  2. 부모 컴포넌트(ParentComponent)에서 자식 컴포넌트(ChildComponent)를 import 하여 부모 컴포넌트에서 참조할 수 있도록 했다.
  3. 부모 컴포넌트 내에서 data라는 이름의 변수를 따로 생성해주고, 그 변수를 return 값인 자식 컴포넌트(ChildComponent)의 속성(message)에 전달했다.

출력 결과:

자식 컴포넌트의 return 값인 this.props.message에 부모 컴포넌트로부터 전달받은 data("Hello from parent!")가 잘 출력된다.


2. children

children은 컴포넌트 태그 사이에 포함된 내용을 나타내는 특별한 prop이다.

예시 코드를 한 번 보면,

// 자식 컴포넌트
import React from 'react';

class ChildComponent extends React.Component {
  render() {
    return (
      <div>{this.props.children}</div>
    );
  }
}
// 부모 컴포넌트
import React from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends React.Component {
  render() {
    return (
      <ChildComponent>
        Hello from parent!
      </ChildComponent>
    );
  }
}

이번에는 props의 이름을 message 대신 children을 부여했고, 부모 컴포넌트에서 자식 컴포넌트로 어떠한 props도 전달하지 않았다.
대신, 자식 컴포넌트의 태그 사이에 텍스트인 "Hello from parent!"를 직접 작성했다.
이 내용이 children prop을 통해 전달되어, 자식 컴포넌트에서 this.props.children을 통해 해당 내용을 사용한다.

출력 결과:

props와 같이 'Hello from Parent'가 잘 출력되는 것을 확인할 수 있다.


이렇게만 보면 propschildren 용례 구분이 잘 안 될 것이다. (내가 그랬으니까)

다음 예제를 한 번 더 보자.
기존 코드에서 자식 컴포넌트를 박스로 감싸는 박스 컴포넌트를 추가했다.

// 자식 컴포넌트
import React from 'react';

class ChildComponent extends React.Component {
  render() {
    return (
      <div>{this.props.message}</div>
    );
  }
}
// 박스 컴포넌트
import React from 'react';

class BoxComponent extends React.Component {
  render() {
    const styles = { 
      border: '4px solid black', 
      padding: '30px', 
      backgroundColor: 'pink' }
    
    return (
      <div style={styles}></div>
      );
  }
}
// 부모 컴포넌트
import React from 'react';
import ChildComponent from './ChildComponent';
import BoxComponent from './BoxComponent';

class ParentComponent extends React.Component {
  render() {
    const data = 'Hello from Parent!';
    return (
      <BoxComponent>
        <ChildComponent message='data'/>
      </BoxComponent>
    );
  }
}

기존 props를 사용하는 자식 컴포넌트를 박스 컴포넌트로 감쌌다. 렌더링 결과는?

우리는 박스 컴포넌트 사이에 자식 컴포넌트 텍스트가 감싸진 형태로 렌더링 될 것을 기대했지만, 렌더링 결과는 그냥 박스 컴포넌트만 나왔다. 왜 그럴까?

앞서 children 속성에 대하여 "컴포넌트 태그 사이에 포함된 내용을 나타내는 속성"이라고 했다.
즉, 박스 컴포넌트 안에 자식 컴포넌트의 내용을 넣고 싶으면 박스 컴포넌트 태그에 받아오는 데이터를 children이라고 명시해주어야 한다.

박스 컴포넌트의 코드를 다음과 같이 수정해보면,

// 박스 컴포넌트
import React from 'react';

class BoxComponent extends React.Component {
  render() {
    const styles = { 
      border: '4px solid black', 
      padding: '30px', 
      backgroundColor: 'pink' }
    
    return (
      <div style={styles}>
        {children}  // 이 부분 추가
      </div>
      );
  }
}


위와 같이 박스 컴포넌트 사이에 있는 내용이 children로 감싸져 내용이 정상적으로 잘 나타나는 것을 볼 수 있다.


3. 함수 컴포넌트로 표현

propschildren을 클래스 컴포넌트 대신 함수 컴포넌트로 표현해보면 다음과 같다.

// Props를 사용한 함수 컴포넌트

const Greet = (props) => {
  return (
    <div>
      <p>Hello, {props.name}!</p>
      <p>Age: {props.age}</p>
    </div>
  );
};
// Children을 사용한 함수 컴포넌트

const Wrapper = (props) => {
  return (
    <div>
      <h2>Wrapper Component</h2>
      <p>{props.children}</p>
    </div>
  );
};

ES6의 Destructuring(비구조화 할당)을 사용하여 다음과 같이 표현할 수도 있다. (이 편이 권장된다.)

// Props를 사용한 함수 컴포넌트

const Greet = ({name, age}) => {
  return (
    <div>
      <p>Hello, {name}!</p>
      <p>Age: {age}</p>
    </div>
  );
};
// Children을 사용한 함수 컴포넌트

const Wrapper = ({children}) => {
  return (
    <div>
      <h2>Wrapper Component</h2>
      <p>{children}</p>
    </div>
  );
};

위의 자식 컴포넌트들을 App.jsx에서 사용하는 것은 다음과 같다.

// 사용 예제

const App = () => {
  return (
    <div>
      {/* Props를 사용한 컴포넌트 */}
      <Greet name="popo" age={25} />

      {/* Children을 사용한 컴포넌트 */}
      <Wrapper>
        <p>This is some content wrapped by Wrapper component.</p>
      </Wrapper>
    </div>
  );
};

출력결과:

profile
Technologically solve everyday challenges

0개의 댓글