본문 바로가기

프론트엔드(Front-End)/React

[REACT] 리액트의 컴포넌트(COMPONENT)

1. REACT의 컴포넌트(Component)란?

  • 리액트는 화면을 컴포넌트(Component) 단위로 구성합니다.
  • 컴포넌트란 화면을 구성할 수 있는 각각의 자바스크립트 파일들을 의미하며 root 태그로 묶여있습니다.
  • 리액트는 이것을 **컴포넌트(Component)**라고 부르며 이것을 기준으로 화면을 렌더링합니다.
  • 컴포넌트가 된 js 파일들은 App.js에서 정말로 부품처럼 사용이 가능합니다.
  • 예컨데, MyCompoent.js 라는 이름을 가진 js 파일은 App.js 에서 <MyComponent /> 태그로 사용 가능합니다.

 

2. 리액트의 컴포넌트 타입

  • 리액트의 컴포넌트는 크게 두가지 타입으로 나뉩니다.
  • 하나는 클래스형 컴포넌트이고 다른 하나는 함수형 컴포넌트 입니다.
  • 함수형 컴포넌트는 본래 리액트 컴포넌트의 state를 다루지 못했었으나, 업데이트로 인해 사용 가능하게 되면서 사용 빈도가 늘어나게 되었습니다.
  • 과거에는 클래스형 컴포넌트가 대세였지만, 지금은 Hook이라는 것이 있기 때문에 함수형 컴포넌트에서도 state를 사용할 수 있습니다.
  • 또한, 함수형 컴포넌트는 LifeCycle을 다룰 수 있기 때문에 요즘 많이 사용하는 추세입니다.
  • 물론 두 컴포넌트 타입 모두 중요하므로 알아 두는 것이 좋습니다.
  • 경우에 따라서 두가지 타입을 번갈아 사용할 수 있는 것이 금상첨화이죠.

 


2.1. 함수형 컴포넌트 예시

function App() {
  let name = "리액트";
  let value = undefined;
  return (
    <>
      <div className="App">
        <div className="innerBox">
          <h1 className="h1-text">아래의 요소는 무엇일까요?</h1>
          {name === "리액트" ? <h2>리액트 입니다.</h2> : <h2>리액트 아닙니다.</h2>}
          <p>{value || "UNDEFINED 입니다."}</p>
          <p>{value}</p>
        </div>
      </div>
      <MyComponent />
    </>
  );
}

export default App;

 

 

2.1.2. 클래스형 컴포넌트

class App extends Component {
  render() {
    const name = "리액트 클래스 컴포넌트";
    return (
      <div className="App">
        <div className="innerBox">
          <p>{name}</p>
        </div>
      </div>
    );
  }
}

export default App;

2.1.3. 함수형 컴포넌트의 축약형

const App = () => {
  return (
    <>
      <div className="App"></div>
      <MyComponent name="React" />
    </>
  );
};
export default App;

3. 다른 컴포넌트를 조합하기

  • 리액트의 컴포넌트는 서로 조합하여 사용 가능합니다.
  • 자바스크립트의 import 덕분인데요. App.js를 작성한 것과 동일하게 컴포넌트를 작성하여 사용할 수 있습니다.

사용자 정의 컴포넌트 작성하기

const MyComponent = () => {
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
      </div>
    </div>
  );
};

export default MyComponent;

 


 

3. props, 부모 컴포넌트로부터 값을 받아오기

  • 리액트는 props를 통해 단방향 데이터 송수신이 가능합니다.
  • 단, 부모 컴포넌트에서 자식 컴포넌트 방향으로만 데이터 전송이 가능합니다.
  • 부모 컴포넌트에서는 자식 컴포넌트 태그의 속성 값으로,
  • 자식 컴포넌트에서는 화살표 함수의 매개변수나, 클래스 컴포넌트는 생성자에서 받아와 사용할 수 있습니다.

3. 1. 컴포넌트에서 props 받아오기

const MyComponent = (props) => {
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
        <p>{props.name}</p> 
				{/* 부모 컴포넌트에서 정한 속성명으로 props 값을 받아옵니다. */}
      </div>
    </div>
  );
};

export default MyComponent;
  • props의 종류는 개발자가 정해주면 됩니다.
  • 그러나, 자식 태그의 경우 열고 닫는 태그들 사이에 어떤 값이나 문자열을 삽입할 수 있는데요.
  • 자식 태그에서도 이러한 값을 받아서 사용할 수 있습니다.
  • 그리고 그 값은 props의 children 프로퍼티를 통해서 가져오게 됩니다.

App.js

const App = () => {
  return (
    <>
      <div className="App"></div>
      <MyComponent>Hello World!</MyComponent>
    </>
  );
};

MyComponent.js

const MyComponent = (props) => {
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
        <p>{props.children}</p>
        {/* 태그 안에 작성된 값은 children으로 가져올 수 있습니다. */}
      </div>
    </div>
  );
};

3. 2. defaultProps, props의 기본 값

  • 자식 컴포넌트에서 prop에 값이 없을 경우에 대처할 수 있는 방법입니다.
  • 부모 컴포넌트에서 값을 넘겨주지 않아도 기본 값을 설정할 수 있습니다.

MyComponent.js

const MyComponent = (props) => {
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
        <p>{props.name}</p>
        {/* props로 주어지지 않더라도 기본 값을 출력 가능합니다.*/}
      </div>
    </div>
  );
};

MyComponent.defaultProps = {
  name: "DEFAULT VALUE",
};

export default MyComponent;

App.js

const App = () => {
  return (
    <>
      <div className="App"></div>
      <MyComponent>Hello World!</MyComponent>
    </>
  );
};

Props의 Destructuring

const MyComponent = (props) => {
  const { name, children } = props;
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
        <p>name : {name}</p>
        <p>children : {children}</p>
        {/* props로 주어지지 않더라도 기본 값을 출력 가능합니다.*/}
      </div>
    </div>
  );
};

MyComponent.defaultProps = {
  name: "DEFAULT VALUE",
};

export default MyComponent;
  • props는 비구조화 문법을 통해서 바로 변수로 만들 수 있습니다.
  • 리액트도 결국은 .js 확장자를 가지는 만큼 Vanilla JavaScript의 여러 문법을 사용할 수 있습니다.
  • 그중에 하나가 es6에서 추가된 javascript destructuring 이라는 문법입니다.
  • 이 문법을 통해 props로 전달된 속성 값을 바로 변수로 받아 사용 가능합니다.

3.3 props와 prototype

  • 컴포넌트의 props는 부모 컴포넌트에서 보내주는 값에 제한을 걸 수 있습니다.
  • 하지만 Java처럼 컴파일 오류나 런타임 오류를 출력하진 않고 개발자 도구 > 콘솔창에서 오류를 출력합니다.
  • 또한, 잘못된 값이 입력되었더라도 값이 그대로 전달은 되는 단점이 있습니다.
  • 그래도, 개발자에게 값이 잘못 들어갔음을 알리는 indicator의 역할은 할 수 있습니다.

MyComponent.js

import ProtoTypes from "prop-types";

const MyComponent = ({ name, children }) => {
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
        <p>name : {name}</p>
        <p>children : {children}</p>
        {/* props로 주어지지 않더라도 기본 값을 출력 가능합니다.*/}
      </div>
    </div>
  );
};

MyComponent.defaultProps = {
  name: "DEFAULT VALUE",
};

// 자바의 자료형 느낌
MyComponent.protoTypes = {
  name: ProtoTypes.string,
};

export default MyComponent;

App.js

import "./App.css";
import "./Custom.css";
import { Component, Fragment } from "react";
import MyComponent from "./MyComponent";

const App = () => {
  return (
    <>
      <div className="App"></div>
      <MyComponent name={3}>Hello World!</MyComponent>
    </>
  );
};
export default App;

3.4. Prototype Required

  • 컴포넌트의 props가 입력되지 않았을 경우 콘솔 창에 경고를 표시하는 역할을 합니다
  • 컴포넌토의 프로토타입 설정 끝에 .isRequired를 붙여서 선언합니다.
import ProtoTypes from "prop-types";

const MyComponent = ({ name, children, number }) => {
  return (
    <div className="component">
      <div className="header">
        <h1>나의 새로운 컴포넌트</h1>
        <p>name : {name}</p>
        <p>children : {children}</p>
        <p>number:{number}</p>
        {/* props로 주어지지 않더라도 기본 값을 출력 가능합니다.*/}
      </div>
    </div>
  );
};

MyComponent.defaultProps = {
  name: "DEFAULT VALUE",
};

// 자바의 자료형 느낌
MyComponent.protoTypes = {
  name: ProtoTypes.string,
  children: ProtoTypes.number,
  number: ProtoTypes.number.isRequired,
};

export default MyComponent;

3. 5. prototypes의 종류

종류 설명 비고

array 배열  
arrayOf 특정 ProtoType으로 이루어진 배열을 의미 arrayOf(Prototypes.number) 와 같이 사용
bool boolean값  
func 함수  
number 숫자형  
object 객체  
string 문자열  
symbol es6의 symbol  
node 렌더링할 수 있는 모든 것 문자열, JSX, chilren 등
instanceOf(클래스) 특정 클래스의 인스턴스 instanceOf(MyClass)
oneOf([]) 기본 값 중에 하나 oneOf([’dog’, ‘cat’])
oneOfType([]) 주어진 배열의 종류중 하나 oneOfType([Prototype.string])
objectOf() 리액트의 프로퍼티 타입, 객체 objectOf(React.Prototypes.number)
shape() 스키마를 가진 객체 shape({name:Prototypes.string})
any 모든 종류  

 


 

4. 클래스 컴포넌트에서 props와 ProtoTypes 사용

4. 1. 1. 클래스 컴포넌트에서의 사용

import { Component } from "react";
import ProtoTypes from "prop-types";

class MyClassComponent extends Component {
  render() {
    const { name, number, children } = this.props; // 비구조화 할당
    return (
      <div className="component">
        <div className="header">
          <h1>나의 새로운 컴포넌트</h1>
          <p>name : {name}</p>
          <p>children : {children}</p>
          <p>number:{number}</p>
          {/* props로 주어지지 않더라도 기본 값을 출력 가능합니다.*/}
        </div>
      </div>
    );
  }
}

MyClassComponent.defaultProps = {
  name: "기본이름",
};

MyClassComponent.prototype = {
  name: ProtoTypes.string,
  number: ProtoTypes.number.isRequired,
};

export default MyClassComponent;

4. 1. 2. 클래스형 컴포넌트의 static

import { Component } from "react";
import ProtoTypes from "prop-types";

class MyClassComponent extends Component {
  static defaultProps = {
    name: "기본이름",
  };
  static protoTypes = {
    name: ProtoTypes.string,
    number: ProtoTypes.number.isRequired,
  };
  render() {
    const { name, number, children } = this.props; // 비구조화 할당
    return (
      <div className="component">
        <div className="header">
          <h1>나의 새로운 컴포넌트</h1>
          <p>name : {name}</p>
          <p>children : {children}</p>
          <p>number:{number}</p>
          {/* props로 주어지지 않더라도 기본 값을 출력 가능합니다.*/}
        </div>
      </div>
    );
  }
}

// MyClassComponent.defaultProps = {
//   name: "기본이름",
// };

// MyClassComponent.protoTypes = {
//   name: ProtoTypes.string,
//   number: ProtoTypes.number.isRequired,
// };

export default MyClassComponent;

4. 2. 함수형 컴포넌트에서의 사용

import ProtoTypes from "prop-types";

const FunctionalComponent = ((props) => {
	const name = props.name;
  return (
    <>
			<div>
					( ... )
			</div>
    </>
  );
};

FunctionalComponent.prototype = {
  name: ProtoTypes.string,
  number: ProtoTypes.number.isRequired,
};

export default FunctionalComponent;

 


 

'프론트엔드(Front-End) > React' 카테고리의 다른 글

[REACT] 컴포넌트 요소의 반복(map, filter)  (0) 2023.01.06
[REACT] 리액트의 ref  (0) 2023.01.05
[REACT] 리액트와 EVENT  (0) 2023.01.04
[REACT] 리액트의 STATE  (0) 2023.01.03
[REACT] React와 JSX  (0) 2022.12.27