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) (1) | 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 |