# 컴포넌트 통신

## 1. 컴포넌트 간 통신이 필요한 이유

React의 클래스 컴포넌트는 캡슐화 되어 있기 때문에 본인의 상태(state)를 가질 수 있어서 관리가 용이하다. 하지만 컴포넌트가 중첩 되었을 때 개별적으로 상태를 관리하는 특징 때문에 상태를 공유하는 것이 까다롭다.&#x20;

{% hint style="info" %}
Ract는 자바 스트립트와 달리 컴포넌트의 상태가 스코프 체인 되지 않는다.&#x20;
{% endhint %}

React 프로그래밍에서는 부모 컴포넌트가 상태를 관리하고, 자손 컴포넌트는 부모 컴포넌트와 통신 하여 상태를 공유 처리한다.&#x20;

## 2. props ⇌ callback

![간단한 컴포넌트 간 통신 ](/files/-MTLx82VKwP7pMCbGn9w)

{% hint style="warning" %}
주의 할 점!&#x20;

* 클래스 컴포넌트에서 이벤트 핸들러를 전달 할 때 클래스 필드 문법을 사용한다면 아래와 같이 사용하기! 아직 익숙하지 않아서 계속 잊어버린다! 기억하기!!&#x20;
  {% endhint %}

{% tabs %}
{% tab title="부모 컴포넌트 Lecturer.js " %}

```javascript
import React, { Component } from 'react'
import PropsTypes from 'prop-types'
import Lecture from './Lecture'

class Lecturer extends Component {
  static propTypes = {
    instructor: PropsTypes.array,
  }

  static defaultProps = {
    instructor: [],
  }

  parentComponentMethod = () => {
    console.log('부모 컴포넌트에 콜백 됨')
  }

  render() {
    return (
      <ul className="lecturers">
        {this.props.instructor.map((lecturer) => (
          <Lecture
            key={lecturer.id}
            lecturer={lecturer}
            // onParentCallback이란 이름으로 Lecture(자식) 컴포넌트에 속성을 보냄
            onParentCallback={this.parentComponentMethod}
          >
            <figure className="lecturer-info">
              <img src={lecturer.image} alt="" className="lecturer-photo" />
              <figcaption>
                {lecturer.module} 모듈을 담당 할 {lecturer.name} 강사 Facebook
                바로가기
              </figcaption>
            </figure>
          </Lecture>
        ))}
      </ul>
    )
  }
}

export default Lecturer

```

{% endtab %}

{% tab title="자식 컴포넌트 Lecture.js " %}

```javascript
import React from 'react'

// onParentCallback 속성을 받아 옴
const Lecture = ({ lecturer, children, onParentCallback }) => (
  <li className="lecturers">
    <a href={lecturer.facebook} rel="noreferer nopener">
      {children}
    </a>
    <button
      type="button"
      className="button-remove-lecturer"
      // 받아온 onParentCallback을 버튼에 이벤트 바인딩
      onClick={onParentCallback}
    >
      제거
    </button>
  </li>
)

export default Lecture

```

{% endtab %}
{% endtabs %}

![](/files/-MT8Pl-78s4pv-SIjWW0)

### 2.1 부모 ➡︎ 자식 (메서드 전달) <a href="#undefined" id="undefined"></a>

```javascript
class Lecturer extends React.Component {
  parentComponentMethood = () => {
    console.log('부모 컴포넌트에 콜백 됨')
  }

  render() {
    return (
      <ul className="lecturers">
        {this.props.instructor.map((lecturer) => (
          <Lecture
            key={lecturer.id}
            lecturer={lecturer}
            onParentCallback={this.parentComponentMethood}
          >
            <figure className="lecturer-info">
              <img src={lecturer.image} alt="" className="lecturer-photo" />
              <figcaption>
                {lecturer.module} 모듈을 담당 할 {lecturer.name} 강사 Facebook
                바로가기
              </figcaption>
            </figure>
          </Lecture>
        ))}
      </ul>
    )
  }
}
```

### &#x20;2.2 부모 ⬅︎ 자식 (메서드 실행) <a href="#undefined" id="undefined"></a>

```javascript
const Lecture = ({ lecturer, children, onParentCallback }) => (
  <li className="lecturers">
    <a href={lecturer.facebook} rel="noreferer nopener">
      {children}
    </a>
    <button
      type="button"
      className="button-remove-lecturer"
      // 받아온 onParentCallback을 버튼에 이벤트 바인딩  
      onClick={onParentCallback}
    >
      제거
    </button>
  </li>
)
```

## 3. 복잡한 컴포넌트 트리 구조

{% embed url="<https://codesandbox.io/s/intelligent-yonath-l9ml0?fontsize=10&hidenavigation=1&theme=dark&view=editor>" %}
복잡한 컴포넌트 트리 구조&#x20;
{% endembed %}

{% hint style="warning" %}
주의하기!&#x20;

* Lecturers에서 App에서 받아온 props의 이벤트 함수에 접근할 때, `this.props.removeLecturer`으로 접근해야 한다. 다시 해석하면 **"클래스(인스턴스)의 부모컴포넌트에서 전달받은 속성(props)중에서 removeLecturer 함수"**&#xC5D0; 접근한다.

```javascript
handleRemoveLecturer={this.props.handleRemoveLecturer}
```

* 앞서 배운 것 처럼 이벤트 함수에 특정 인자를 전달 할 때, 화살표 함수 또는 `bind()` 사용하기! 만약 사용하지 않는다면 이벤트가 발생하기 전에 함수가 실행된다.&#x20;

```javascript
onClick={() => handleRemoveLecturer(lecturer.id)}
```

* `setState()`를 사용해서 상태 업데이트 하는거 계속 잊어버린다. 조심하기!&#x20;

```javascript
this.setState({
      FEML_lecturers: filteredLecturers,
    })
```

{% endhint %}

## 참고&#x20;

* [React 끌어올리기 ](https://ko.reactjs.org/docs/lifting-state-up.html#lifting-state-up)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shhn0509.gitbook.io/react/react-study/react/communication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
