리액트 컴포넌트는 클래스형 컴포넌트
와 함수형 컴포넌트
로 작성된다.
차이점은 클래스형 컴포넌트
는 state
기능 및 생명 주기 함수
기능을 사용할 수 있다는 것과 임의 메서드를 정의할 수 있다는 것.
리액트 16.8버전부터 훅(Hook)
이 등장하면서 함수형 컴포넌트
에서도 상태값과 생명 주기 함수
를 작성 할 수 있게 되었다.
1. 클래스형 컴포넌트
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
</div>
);
}
}
export default App;
class
키워드 필요클래스형 컴포넌트
에서는 render
함수가 꼭 있어야 하고, 그 안에서 보여주어야 할 JSX
를 반환해야한다.Component
로 상속 받아야 함state
, 생명 주기 함수
관련 기능사용이 가능props
를 조회할 때 this
키워드 사용함수형 컴포넌트
보다 메모리 자원을 더 사용한다.2. 함수형 컴포넌트
import React from 'react';
const App = () => {
return (
<div>
</div>
);
};
export default App;
함수형 컴포넌트
의 장점
클래스형 컴포넌트
보다 선언하기가 훨씬 편하다.클래스형 컴포넌트
보다 덜 사용한다.함수형 컴포넌트
의 단점
state
와 생명 주기 함수
API의 사용이 불가능 (리액트 16.8버전 업데이트 이후 Hooks
라는 기능이 도입되면서 해결 클래스형 컴포넌트
와 똑같이 사용할 수 있는 것은 아니지만 조금 다른 방식으로 비슷한 작업을 할 수 있게 되었음)🕵️♀️state : 컴포넌트 내부에서 바뀔 수 있는 값
1. 클래스형 컴포넌트
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props)
this.state = {
test1: [],
test2: '',
number: 1
}
}
testFunction = () => {
this.setState({number : number + 1})
}
render() {
const name = '클래스형 컴포넌트'
return (
<div>
{name}
</div>
);
}
}
export default App;
constructor
안에서 this.state
초기 값 설정 가능constructor
없이도 바로 state
초기 값을 설정가능this.setState
를 통해 state
값을 변경클래스형 컴포넌트
의 state
는 객체형식2. 함수형 컴포넌트
import React, {useState} from 'react';
const App = () => {
const [test1, setTest1] = useState([])
const [test2, setTest2] = useState('')
const [number, setNumber] = useState(1)
const testFunction = () => {
setNumber(number + 1)
}
const name = '함수형 컴포넌트'
return (
<div>
{name}
</div>
);
};
export default App;
useState
함수로 state
를 사용한다.useState
함수를 호출하면 배열이 반환되는데 첫 번째 원소는 현재 상태, 두번째 원소는 상태를 바꿔주는 함수이다.constructor(props){ super(props); }
React
에서 component
를 생성할 때 state
값을 초기화 하거나 메서드를 바인딩 할 때 constructor
를 사용한다. React
의 component
생성자는 해당 component
가 마운트 되기 전 호출된다. React.Component
를 상속한 컴포넌트의 생성자를 구현할 때 super(props)
사용을 권고하고 있다. 왜냐하면 this.props
사용 시 생성자 내에서 정의되지 않아 버그 발생이 될 수 도 있기 때문
📣 주의 : constructor
를 사용할때 생성자 내에서는 setState
를 사용하지 말고 this.state
로 초기값을 할당한다. (그 외에는 this.setState
를 사용)
🕵️♀️props : React
가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX
어트리뷰트와 자식을 해당 컴포넌트에 단일 객체로 전달한다. 이 객체를 props
라고 한다.
1. 클래스형 컴포넌트
import React, { Component } from 'react';
class App extends Component {
render() {
/* 클래스형 컴포넌트 */
const {number, testName} = this.props
return (
<div>
{testName}의 나이는 {number}살 입니다.
</div>
);
}
}
export default App;
this.props
로 통해 값을 불러올 수 있다.2. 함수형 컴포넌트
import React from 'react';
const App = ({number, testName}) => {
/* 함수형 컴포넌트 */
return (
<div>
{testName}의 나이는 {number}살 입니다.
</div>
);
};
export default App;
props
를 불러올 필요 없이 바로 호출 할 수 있다.🕵️♀️props : properties(프로퍼티) 의 줄임말이다. 상위 컴포넌트가 하위 컴포넌트에 값을 전달할때 사용한다.
(단방향 부모->자식), 수정 불가능 (자식은 읽기 전용 데이터)
📣사용법
프로퍼티에 문자열을 전달할 때 ""
를 사용하여 작성하고, 그외의 값은 {}
를 사용한다.
- props 지정하기
import React, {Component} from 'react';
import Melon from './component/Melon'
class App extends Component {
render() {
return (
<div className='App'>
<Melon name = "NUYHES Blog"/>
</div>
);
}
}
export default App;
<Melon/>
컴포넌트를 불러와서 사용하는 부모 컴포넌트 App.js
에 넣은 코드이다. <Melon name = "NUYHES Blog"/>
에 props
의 name
의 속성값을 NUYHES Blog
로 지정하고 있다.
- props 사용하기
import React, { Component } from 'react';
class Melon extends Component {
render() {
return (
<h1>Hello {this.props.name}</h1>
);
}
}
export default Melon;
Melon
에서는 부모 컴포넌트에서 지정했던 name
속성값을 사용 할 수있다. props
를 렌더링하기 위해 JSX
내부 {}
안에 작성하고 this.props.name
을 사용하여 props의 name속성값에 접근하는 것을 확인할 수 있다.
- defaultProps 사용하기
부모 컴포넌트에서 props
를 지정하지 않았을 때 defaultProps
를 통해 정의한 default 값을 사용할 수 있다.
import React, {Component} from 'react';
import Melon from './component/Melon'
class App extends Component {
render() {
return (
<div className='App'>
<Melon/>
</div>
);
}
}
export default App;
☝☝이렇게 부모 컴포넌트인 App.js
에서 Melon
의 props
값을 지정하지 않았을때
import React, { Component } from 'react';
class Melon extends Component {
render() {
return (
<h1>Hello {this.props.name}</h1>
);
}
}
Melon.defaultProps = {
name : "defaultProps입니다."
}
export default Melon;
☝☝ 자식 컴포넌트에 Melon.defaultProps
를 만들어 name
을 만들어 지정한다.
☝☝ defaultProps
를 통해 default 값을 지정하지 않았다면 name : "defaultProps입니다."
값이 나오지 않고 Hello
가 나오고 뒤에는 공백일 것이다. (부모 컴포넌트에서 지정하지 않았으므로) 하지만 defaultProps
를 통해 name의 default값을 defaultProps입니다.라고 지정한 값을 렌더링해준다.
- propTypes를 통한 props 검증하기
propTypes
를 통해 부모 컴포넌트로 부터 지정된 props
속성을 검증할 수 있다. 필수로 지정되어야 할 속성이 지정되지 않았거나 특정 type
에 대한 props
가 다른 type
으로 설정되었을 경우에 이를 검증할 수 있는 코드를 작성 할 수 있다. propTypes
을 통해 검증코드를 작성하는 방법은 defaultProps
작성법과 비슷하다.
import React, { Component } from 'react';
import propTypes from "prop-types"
class Melon extends Component {
render() {
return (
<h1>Hello {this.props.name}</h1>
);
}
}
Melon.propTypes = {
name : propTypes.string.isRequired
}
export default Melon;
☝☝먼저 propTypes
를 사용하기 위해 import
한다. 모듈 export
코드 위가 바로 propTypes
를 통해 props
를 검증하는 코드이다. 해석하자면 name
속성은 반드시 부모 컴포넌트에서 지정되어야 하며 Data Type
은 string
으로 지정하라는 의미로 해석할 수 있다.
import React, {Component} from 'react';
import Melon from './component/Melon'
class App extends Component {
render() {
return (
<div className='App'>
<Melon name = {1}/>
</div>
);
}
}
export default App;
부모 컴포넌트인 App.js
에서 일부러 name
의 속성을 Number Type으로 지정하고 실행해본다.
브라우저 콘솔
에는 name
의 type
이 잘못되었다고 경고해주고 있다.
[출처]https://lktprogrammer.tistory.com/118
1. 클래스형 컴포넌트
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props)
this.state = {
number:1
}
}
onClickFn = () => {
this.setState({number : number+1})
}
render() {
return (
<div>
<button onClick={this.onClickFn}>버튼</button>
</div>
);
}
}
export default App;
this.
를 붙여줘야한다.2. 함수형 컴포넌트
import React from 'react';
const App = () => {
const [number, setNumber] = useState('')
const onClickFunc = ()=>{
setNumber(number + 1)
}
return (
<div>
<button onClick={onClickFunc}>+1 버튼</button>
</div>
);
};
export default App;
const
+ 함수 형태로 선언해야 한다.this
가 필요없다.React에서 컴포넌트는 여러 종류의 "생명주기 메소드"
를 가지며 이 메소드를 오버라이딩(상속하여 재정의)
하여 특정 시점에 코드가 실행되도록 설정한다.
클래스 컴포넌트
에만 해당되는 내용이며, 함수형 컴포넌트
는 Hook
을 사용하여 생명주기에 원하는 동작을 한다.
1. 클래스형 컴포넌트
컴포넌트가 인스턴스로 생성되고 DOM 트리에 삽입되어 브라우저상에 나타나는 과정
constructor
👇예시👇
constructor(props){
super(props)
this.state={
number: 1
}
}
getDerivedStateFromProps
👇예시👇
static getDerivedStateFromProps(nextProps, prevState){
if(prevState.value !== nextProps.value){
return{
value: nextProps.value
}
}
return null
}
render
👇예시👇
render(){
const title = '클래스형 컴포넌트'
return(
<div>
<button onClick={this.onClickFunc}>+1버튼</button>
</div>
)
}
componentDidMount
컴포넌트 props 또는 state가 바뀌었을 때
getDerivedStateFromProps
생성 될 때 (Mounting)
에서 등장한 메서드로 업데이트에서도 호출이 된다.
shouldComponentUpdate
👇예시👇
shouldComponentUpdate(nextProps, nextState) {
return this.props.value !== nextProps.value
}
render
생성 될 때 (Mounting)
에서 등장한 메서드로 업데이트에서도 호출이 된다.
getSnapshotBeforeUpdate
render()->getSnapshotBeforeUpdate->DOM에 변화 반영->componentDidUpdate)
componentDidUpdate
컴포넌트가 브라우저상에서 사라질때
componentWillUnmount
componentDidCatch
👇예시👇
class App extends Component{
state = {
error:false
}
componentDidCatch(error, info){
this.setState({
error: true
})
}
render(){
if(this.state.error){
return<h1>에러</h1>
}
return(
<div>
<TodoListTemplate form={<From/>}>
<TodoItemList/>
</TodoListTemplate>
</div>
)
}
}
export default App