React 에서 Component 를 사용하는 방법에는 크게
1. Class Component
,2. Functional Component
가 존재하는 것은 알고 있을 것이다.
이번 포스팅에서는 주로 사용하던Functional Component
에서보다Class Component
에서 지나쳤던 내용 위주로 정리한다.
defaultProps
부모 컴포넌트에서 자식 컴포넌트로
props
값을 따로 지정하지 않았을 때 보여 줄 기본값을 설정하는 것이다.
// App.js
import React, { Component } from "react";
import MyComponent from "./MyComponent";
class App extends Component {
render() {
return (
<div className="container">
<MyComponent />
</div>
);
}
}
export default App;
// MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
render() {
return (
<div>
My "{this.props.name}" Component Container 생성
<br />
제가 좋아하는 숫자는 {this.props.favoriteNumber} 입니다.
</div>
);
}
}
MyComponent.defaultProps = {
name: "기본 이름",
favoriteNumber: 3,
};
App.js
에서 MyComponent
컴포넌트를 import
해서 렌더링을 했다.App.js
에 MyComponent
컴포넌트에서 name
, favoriteNumber
에 대한 props
를 넘겨주지 않았다.MyComponent
컴포넌트 내부에서 defaultProps
를 위에 코드와 같이 설정해놓으면, props
로 값을 넘기지 않아도, 해당 컴포넌트에서 사용하는 props
에 대해 기본 값으로 사용할 수 있다.Children
리액트 컴포넌트를 사용할 때 컴포넌트 태그 사이의 내용을 보여 주는
props
이다.
// App.js
import React, { Component } from "react";
import MyComponent from "./MyComponent";
class App extends Component {
render() {
return (
<div className="container">
<MyComponent>React!!</MyComponent>
</div>
);
}
}
export default App;
// MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
render() {
return (
<div>
My "{this.props.name}" Component Container 생성
<br />
children 값은 {this.props.children} 입니다.
<br />
제가 좋아하는 숫자는 {this.props.favoriteNumber} 입니다.
</div>
);
}
}
MyComponent.defaultProps = {
name: "기본 이름",
favoriteNumber: 3,
};
App.js
에서 MyComponent
컴포넌트를 Self Closing 방식이 아닌, 태그 사이에 내용 이 존재하면(텍스트 && 태그도 상관없음)MyComponent
에서 props.children
으로 사용가능클래스 컴포넌트 의 경우,
props
값을 조회할 때마다props.속성명1
,props.속성명2
... 이런 식으로 앞에 매번props.
키워드를 앞에 붙여줘야 된다.
이 방식을 좀 더 간편하게 할 수 있는 방식이 있다.
// MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
render() {
// Destructuring(분해할당)
const { name, favoriteNumber, children } = this.props;
return (
<div>
My "{name}" Component Container 생성
<br />
children 값은 {children} 입니다.
<br />
제가 좋아하는 숫자는 {favoriteNumber} 입니다.
</div>
);
}
}
MyComponent.defaultProps = {
name: "기본 이름",
favoriteNumber: 3,
};
export default MyComponent;
Destructuring
을 사용할 경우, 더 이상 클래스 컴포넌트 props
에 대해 앞에 this.props.
을 붙이지 않아도 됨으로 간략화 할 수 있다.propTypes
를 통한 props 검증컴포넌트의 필수
props
를 지정하거나props
의타입(type)
을 지정할 때는propTypes
를 사용한다.
// MyComponent.js
import React, { Component } from "react";
import PropTypes from "prop-types"; // PropTypes import
class MyComponent extends Component {
render() {
const { name, favoriteNumber, children } = this.props;
return (
<div>
My "{name}" Component Container 생성
<br />
children 값은 {children} 입니다.
<br />
제가 좋아하는 숫자는 {favoriteNumber} 입니다.
</div>
);
}
}
MyComponent.defaultProps = {
name: "기본 이름",
favoriteNumber: 3,
};
// propTypes
// 각 props 에 대해 PropTypes.타입 형식으로 지정가능하다.
MyComponent.propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired,
children: PropTypes.node,
};
export default MyComponent;
propsTypes
으로 설정한 타입에 맞지 않게 값을 넘겨 받아 사용할 경우, 경고를 보여준다.PropTypes 에 대한 것은 확인해야 할 것이 더 있다.
예를 들어
isRequired
설정
PropTypes
종류에는 array
, arrayOf
, bool
, func
, number
, object
, string
, symbol
, node
, instanceOf
, oneOf
, oneOfType([React.PropsTypes.string, PropTypes.number])
, objectOf(React.PropTypes.number)
등이 있다.
앞서 설명한
defaultProps
,PropTypes
는 필수는 아니다.
하지만, 큰 규모의 프로젝트의 경우, 특히 다른 개발자들과 협업하는 과정이 있다면, 해당 컴포넌트에 어떤 props 가 필요한지 쉽게 알 수 있어 개발 능률이 좋아질 수 있다.
(Class)
클래스형 컴포넌트 stateimport React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
// state 초기값 설정하기
this.state = {
number: 0
}
}
render() {
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
// this.setState 를 사용하여 state 에 새로운 값을 넣을 수 있다.
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
constructor
: 컴포넌트 생성자 메서드, 작성 시 super
키워드 반드시 필요클래스 컴포넌트에서
state
는 객체형식이어야 한다.
state
객체 안에는 여러 값이 존재할 수 있다.this.setState({ 키 : 새로운 값 })
업데이트 가능하다.(Class)
state 를 constructor 에서 꺼내기import React, { Component } from "react";
class Counter extends Component {
// state 를 constructor 밖으로 꺼냄
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
(Class)
this.setState 에 객체 대신 함수 인자 전달하기 (비동기 제어)
this.setState
를 사용하여 state 값을 업데이트할 때는 상태가비동기적
으로 업데이트 된다.
// 비동기 처리없이, 이벤트 한번에 state 두 번 변경 시
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
// state 변경, 비동기 처리(= 객체 대신에 "함수"를 인자로 넘겨준다.)
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState((prevState) => {
return {
number: prevState.number + 1,
};
});
this.setState((prevState) => {
return {
number: prevState.number + 1,
};
});
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
(Class)
this.setState 가 끝난 후 특정 작업 실행하기 (비동기 제어)
setState
를 사용하여 값을 업데이트하고 난 다음에 특정 작업을 하고 싶을 때는 setState 의 두 번째 파라미터로콜백함수(callback)
를 등록하여 작업을 처리하면, 동기적으로 처리가 가능하다.
// this.setState 에 두 번째 파라미터로 callback 함수를 전달
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState({ number: number + 1 }, () => {
console.log("방금 setState 호출 되었습니다.");
console.log(this.state);
});
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
객체 사본을 만들고, 그 사본에 값을 업데이트한 후, 그 사본의 값을 setState 혹은 세터함수를 통해 업데이트해야 한다.
props
를 사용한다고 값이 무조건 고정적이지는 않는다.이번 포스팅에서는 주로 다루지 않았던
Class Component
를 주로, 그것도 대부분 기본적인 내용만 살펴봤다. 이후에는 다루지 않았던Functional Component
에 대해 더욱 자세히 살펴본다. (현재 React 는 hooks 의 시대이다.)
개념