function Welcome(props) { // 컴포넌트이름은 무조건 PascalCase로 작성한다.
return <h1>Hello, {props.name}</h1>;
}
리액트에서 클래스 컴포넌트는 React.Component를 상속 받아 작성한다. 클래스 컴포넌트는 props라는 매개변수를 받아오고 render 함수를 통해 표시할 뷰 계층 구조를 반환한다.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
장점
단점
JavaScript Class 참조 문서
💡
render()
함수render 함수는 화면에서 보고자 하는 내용을 반환한다. React는 설명을 전달받고 결과를 표시한다. 특히 render는 렌더링할 내용을 경량화한 React 엘리먼트를 반환한다. 다수의 React 개발자는 “JSX”라는 특수한 문법을 사용하여 React의 구조를 보다 쉽게 작성한다.
구문은 빌드하는 시점에서React.createElement('div')
로 변환된다.
// 작성 코드
ReactDOM.render(
<div>
<h1>Hello World</h1>
</div>
);
// 트랜스파일링 된 코드
ReactDOM.render(
React.creatElement("div", null,
React.creatElement("h1", null, "Hello World")
)
)
// 기존 HTML 태그로 리액트 엘리먼트 작성
const element = <h1>Hello, World</h1>;
// 사용자 정의 컴포넌트를 이용해 리액트 엘리먼트 작성
function Welcome(props) {
return <h1>Hello, World</h1>;
}
const element = <Welcome/>;
// 컴포넌트 이름을 태그 형식으로 작성하여 리액트 엘리먼트를 표현한다.
<div/>
는 HTML div 태그를 나타내지만, <Welcome />
은 컴포넌트를 나타내며 범위 안에 Welcome이 있어야한다.// 1. 컴포넌트 내부에서 props 사용
// 함수 컴포넌트에서 props 사용하기
function Welcome(props) {
// JSX에서 JS 문법을 사용하므로 중괄호를 사용한다.
return <h1>Hello, {props.name}</h1>;
}
// 클래스 컴포넌트에서 props 사용하기
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
// 클래스 컴포넌트에서 props 사용 시 this 키워드는 필수
}
}
// 2. 리액트 엘리먼트에 props 추가하기 - 공통
ReactDom.render( // 컴포넌트에서 작성한 동일한 이름의 엘리먼트 속성 추가
<div>
<Welcome name="stranger"/>
</div>,
document.querySelector('#container')
);
// 속성을 추가하는 방식은 기존의 HTML 엘리먼트에 속성(attribute)를 추가하는 방식과 같다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
ReactDom.render(
<div>
<Welcome name="stranger"/>
</div>,
document.querySelector('#container')
);
<Welcome name="stranger"/>
이라는 리액트 엘리먼트를 매개변수에 담아 ReactDom.render()
함수를 호출한다.ReactDom.render()
함수 호출 시 리액트는 {name: 'stranger'}
를 props로 하여 Welcome 컴포넌트를 호출한다.<h1>Hello, stranger</h1>
를 반환한다.<h1>Hello, stranger</h1>
와 같도록, DOM을 효율적으로 업데이트 한다.class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
ReactDom.render(
<div>
<Welcome name="stranger"/>
</div>,
document.querySelector('#container')
);
<Welcome name="stranger"/>
이라는 리액트 엘리먼트를 매개변수에 담아 ReactDom.render()
함수를 호출한다.ReactDom.render()
함수 호출 시 리액트는 Welcome 클래스의 생성자(Constructor)를 호출한다.render()
함수에서는 this.props.prop이름
으로 props에 접근 할 수 있다.render()
함수가 반환한 <h1>Hello, stranger</h1>
와 같도록, DOM을 효율적으로 업데이트 한다.// 다른 엘리먼트 안에 포함 된 리액트 엘리먼트
ReactDom.render(
<div>
<Welcome/>
</div>,
document.querySelector('#container')
);
// 다른 엘리먼트를 포함하고 있는 리액트 엘리먼트
ReactDom.render(
<Welcome>
<p>Hello World</p>
</Welcome>,
document.querySelector('#container')
);
this.props.children
으로 자식 요소에 접근 가능하다.// 클래스형 컴포넌트
class Welcome extends React.Component {
render () {
const style = {
color: {this.props.textColor}
// 리액트 엘리먼트에 작성한 textColor 이름의 속성이 전달
};
return(
<h1 style={style}>Welcole {this.props.children}</h1>
// 리액트 엘리먼트 내부에 작성한 텍스트 노드가 전달
);
}
}
// 함수헝 컴포넌트
const Welcome = (props) => {
const style = {
color: {props.textColor}
};
return (
<h1 style={style}>Welcole {props.children}</h1>
);
}
ReactDom.render(
<Welcome textColor="green">World<Welcome/>,
document.querySelector('#container')
);
this.props.children
은 문자열을 반환하고, 자식 노드가 단일 엘리먼트라면 배열로 감싸지 않은 단일 컴포넌트를 리턴한다.undefined
로 인해 생기는 오류를 방지할 수 있다. props type 검증을 통해 props의 값이 필수인지 아닌지, 지정한 타입과 맞는지 아닌지를 검증하여 지정한 type과 틀리다면 console에서 경고 메시지를 띄우는 등의 작업을 할 수 있다. 이러한 작업들은 유지보수에도 좋고 다른 개발자가 코드를 봤을 때 쉽게 이해할 수 있도록 돕는다.Component.propTypes = {
propName: PropTypes.dataType[.isRequired] // isRequired의 경우 필수 속성
}
// 어떤 타입이든 허용할 때는 any, 리액트 엘리먼트일 경우 element
Component.defaultProps = {
propName: defaultValue
}
class User extends React.Component {
render(
return (
<div>
<p>name : {this.props.name}</p>
<p>age : {this.props.age}</p>
<p>profile : {this.props.children}</p>
</div>
);
);
}
// 타입 검증
User.propTypes = {
name: PropTypes.string, // string 타입
age: PropTypes.number.isRequired // number 타입, 필수값
}
// 기본값 설정
User.defaultProps = {
name: 'Unknown' // 전달받은 name이라는 이름을 가진 props가 없을 경우 기본값 설정
}
ReactDom.render(
<User age="25">Hi. It's me<User/>,
document.querySelector('#app')
);
npm i prop-types
import React from "react";
import PropTypes from "prop-types"; // prop-types 모듈 import
const User = (props) => {
return (
<div>
<p>name : {props.name}</p>
<p>age : {props.age}</p>
<p>profile : {props.children}</p>
</div>
);
};
// 타입 검증
User.propTypes = {
name: PropTypes.string, // string 타입
age: PropTypes.number.isRequired // number 타입, 필수값
children: PropTypes.node.isRequired // 자녀노드 필수
}
// 기본값 설정
User.defaultProps = {
name: 'Unknown' // 전달받은 name이라는 이름을 가진 props가 없을 경우 기본값 설정
}
export default User;
*PropTypes 종류 더 알아보기class RootComp extends React.Component {
render() {
return (
<Parent color={this.props.color}
num={this.props.num}
size={this.props.size}
/>
);
}
}
class Parent extends React.Component {
render() {
return (
<Child color={this.props.color}
num={this.props.num}
size={this.props.size}
/>
);
}
}
class Child extends React.Component {
render() {
return (
<div>
<p>{this.props.color}</p>
<p>{this.props.num}</p>
<p>{this.props.size}</p>
</div>
)
}
}
ReactDOM.render(
<div>
<RootComp color='blue' num='12' size='medium'/>
</div>,
document.getElementById('app')
);
// RootComp -> Parent -> Child로 props를 전달
// Child에서는 전달받은 props를 출력
// Parent는 Child로 전달만 할 뿐 props를 실제로 사용하지 않음
// props object
var props = {
color: 'blue',
num: 12
size: 'medium'
}
// props를 전달하기 위해서는 props 객체의 모든 속성에 하나하나 접근 해야 한다.
<Parent color={this.props.color}
num={this.props.num}
size={this.props.size}
/>
class RootComp extends React.Component {
render() {
return (
<Parent {...this.props}/>
);
}
}
class Parent extends React.Component {
render() {
return (
<Child {...this.props}/>
);
}
}
class Child extends React.Component {
render() {
return (
<div>
<p>{this.props.color}</p>
<p>{this.props.num}</p>
<p>{this.props.size}</p>
</div>
)
}
}
ReactDOM.render(
<div>
<RootComp color='blue' num='12' size='medium'/>
</div>,
document.getElementById('app')
);