React 컴포넌트 간 데이터 전달 방식 정리

Props를 통한 부모 → 자식 데이터 전달

React에서 컴포넌트는 기본적으로 독립적인 단위이므로 외부로부터 데이터를 받기 위해서는 props를 사용해야 합니다. props는 컴포넌트에 전달되는 읽기 전용 입력값입니다.


// 부모 컴포넌트에서 속성으로 데이터 전달
<UserProfile name="김민수" age={28} isActive />

// 함수형 컴포넌트: 매개변수로 props 수신
function UserProfile(props) {
  return (
    <div>
      이름: {props.name}, 나이: {props.age}, 상태: {props.isActive ? '활성화' : '비활성화'}
    </div>
  );
}

// 클래스형 컴포넌트: this.props로 접근
class UserProfile extends React.Component {
  render() {
    return <div>반갑습니다, {this.props.name}님!</div>;
  }
}

Props 특징

  • 임의의 자료형 전달 가능 (문자열, 숫자, 배열, 객체, 함수, JSX 등)
  • 읽기 전용 – 수정 불가능
  • 클래스 컴포넌트 생성자에서 super(props) 호출 필수

class UserProfile extends React.Component {
  constructor(props) {
    super(props); // 반드시 props 전달
    console.log(this.props.name); // 생성자 내에서도 접근 가능
  }
  render() {
    return <div>{this.props.name}</div>;
  }
}

자식 → 부모 데이터 전달: 콜백 함수 활용

자식 컴포넌트가 부모에게 데이터를 전달하려면, 부모가 콜백 함수를 props로 전달하고, 자식이 이를 호출하는 방식을 사용합니다.


class Parent extends React.Component {
  handleChildData = (data) => {
    console.log('자식으로부터 받은 데이터:', data);
  };

  render() {
    return <Child onSubmit={this.handleChildData} />;
  }
}

class Child extends React.Component {
  state = { message: 'Hello from child' };

  handleClick = () => {
    this.props.onSubmit(this.state.message);
  };

  render() {
    return <button onClick={this.handleClick}>데이터 전송</button>;
  }
}

형제 컴포넌트 간 통신: 상태 승격 (Lifting State Up)

두 자식 컴포넌트가 같은 데이터를 공유해야 할 경우, 공통 부모 컴포넌트에 상태를 두고 각각 props로 전달합니다.


class SharedCounter extends React.Component {
  state = { count: 0 };

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <Display count={this.state.count} />
        <IncrementButton onInc={this.increment} />
      </div>
    );
  }
}

const Display = ({ count }) => <h2>현재 값: {count}</h2>;
const IncrementButton = ({ onInc }) => <button onClick={onInc}>+1</button>;

깊은 중첩 컴포넌트 간 데이터 전달: Context API

여러 계층을 거쳐 props를 전달하는 번거로움을 줄이기 위해 Context를 사용할 수 있습니다. 주로 테마, 언어 설정 등 전역 상태 관리에 적합합니다.


// Context 생성
const ThemeContext = React.createContext('light');

// Provider로 감싸서 데이터 제공
class App extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <NavigationBar />
      </ThemeContext.Provider>
    );
  }
}

// Consumer 또는 useContext로 데이터 사용
const NavigationBar = () => (
  <ThemeContext.Consumer>
    {theme => <nav className={theme}>내비게이션 바</nav>}
  </ThemeContext.Consumer>
);

컴포넌트 자식 요소 다루기: children Prop

children은 특수한 prop으로, 태그 사이에 포함된 내용을 나타냅니다. 이는 문자열, 엘리먼트, 컴포넌트, 함수까지 포함할 수 있어 유연한 구조를 가능하게 합니다.


function Card({ children }) {
  return <div className="card" style={{ padding: '20px', border: '1px solid #ccc' }}>{children}</div>;
}

// 사용 예시
<Card>
  <h3>카드 제목</h3>
  <p>이것은 카드 내용입니다.</p>
</Card>

Props 검증: PropTypes

외부에서 전달받는 props의 형식을 검사하여 실수를 조기에 발견할 수 있습니다. 개발 환경에서만 동작하며, 코드 안정성을 높여줍니다.


import PropTypes from 'prop-types';

function UserCard({ name, age, avatar, tags }) {
  return (
    <div>
      <img src={avatar} alt="프로필" />
      <h4>{name} ({age})</h4>
      <ul>
        {tags.map(tag => <li key={tag}>{tag}</li>)}
      </ul>
    </div>
  );
}

UserCard.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  avatar: PropTypes.string,
  tags: PropTypes.arrayOf(PropTypes.string)
};

UserCard.defaultProps = {
  age: 20,
  tags: []
};

Props 기본값 설정

특정 props가 전달되지 않았을 때 사용할 기본값을 지정할 수 있습니다. 재사용 가능한 컴포넌트 설계에 매우 유용합니다.


function Pagination({ pageSize, onPageChange }) {
  return (
    <div>
      페이지 크기: {pageSize}
      <button onClick={() => onPageChange(1)}>다음 페이지</button>
    </div>
  );
}

Pagination.defaultProps = {
  pageSize: 10,
  onPageChange: () => {}
};

태그: React props Context API 컴포넌트 통신 PropTypes

6월 21일 22:56에 게시됨