티스토리 뷰
이 글은 생활코딩의 React class & function style coding 수업을 듣고 정리한 내용입니다.
수업내용
React는 class와 function 두 가지 방법으로 작성할 수 있다.
class 방식은 React의 모든 기능을 사용할 수 있지만 해당 문법을 모두 알아야 하고, function 방식은 간편하지만 state를 만들거나 life cycle API를 사용할 수 없이 상위 컴포넌트가 시키는 일만 해야 했다. 하지만, hook이 도입되면서 function 방식도 내부적으로 상태(state)를 다루고, 라이프 사이클에 따른 작업을 정의할 수 있게 되었다. 그러면서 함수형의 간편함은 그대로 가진다.
생활코딩의 React class & function style coding 수업은 같은 일을 하는 컴포넌트를 class와 function 두 가지 방식으로 각각 작성해보며 서로의 차이를 알고 이해하기 위한 수업이다.
React class vs function
기본 형태
class
import React from 'react'
export default class ClassComp extends React.Component {
render() {
return (
<div className="container">
<h2>Class Style Component</h2>
</div>
)
}
}
render()
함수에서return
function
import React from 'react'
export default function FuncComp() {
return (
<div className="container">
<h2>Function Style Component</h2>
</div>
)
}
- 그 자체에서
return
state
컴포넌트의 상태 정보를 가지는 state
에 대해 실습하기 위해 App
컴포넌트에서 initNumber
를 전해준다. 하위 컴포넌트에서는 전달받은 initNumber
를 state
에 저장후 화면에 출력한다. 이후, 랜덤한 숫자로 상태를 업데이트해주는 버튼을 추가한다.
App.js
export default class App extends React.Component {
render() {
return (
<div className="container">
<FuncComp initNumber={2}></FuncComp>
<ClassComp initNumber={2}></ClassComp>
</div>
)
}
}
class
export default class ClassComp extends React.Component {
state = {
number: this.props.initNumber
}
render() {
return (
<div className="container">
<h2>Class Style Component</h2>
<p>Number : {this.state.number}</p>
<input type="button" value="random" onClick={
function () {
this.setState({ number: Math.random() })
}.bind(this)
} />
</div>
)
}
}
state
에 상태관리this.props
사용this.state
에서 상태 정보 가져옴setState()
로 상태 업데이트
function
import React, { useState } from 'react'
export default function FuncComp(props) {
const [number, setRandomNumber] = useState(props.initNumber)
return (
<div className="container">
<h2>Function Style Component</h2>
<p>Number : {number}</p>
<input type="button" value="random" onClick={
function () {
setRandomNumber(Math.random())
}
} />
</div>
)
}
- 첫 번째 파라미터로
props
를 받아옴 import {useState} from 'react'
- React hook의
useState()
를 이용하여 상태 관리 useState()
의 인자는 state의 초기 값[state 변수 이름, state를 업데이트하는 함수]
<- 배열 구조 분해 문법으로 아래와 같은 일을 한다const numberState = useState(props.initNumber) const number = numberState[0] const setRandomNumber = numberState[1]
React Lifecycle
class
export default class ClassComp extends React.Component {
state = {...}
// 처음 컴포넌트를 그리기 전 사전작업
// 이후 render() 호출
componentWillMount() {
console.log('class => componentWillMount')
}
// 처음 컴포넌트를 render한 이후 호출
componentDidMount() {
console.log('class => componentDidMount')
}
// 기존 props, state와 새로운 값을 비교하여 render를 호출해야 하는지 검사
// return값이 true이면 componentWillUpdate 호출
shouldComponentUpdate(nextProps, nextState) {
console.log('class => shouldComponentUpdate')
return true
}
// 컴포넌트를 다시 그리기 전 호출
componentWillUpdate(nextProps, nextState) {
console.log('class => componentWillUpdate')
}
// 컴포넌트를 다시 그리고 호출
componentDidUpdate(nextProps, nextState) {
console.log('class => componentDidUpdate')
}
// 컴포넌트를 화면에 그림
render() {
console.log('class => render')
return (...)
}
}
function
export default function FuncComp(props) {
const [number, setRandomNumber] = useState(props.initNumber)
// 두 번째 인자인 배열내의 것의 상태가 바뀌면 첫 번째 인자인 콜백함수 호출
// 빈 배열 전달 시 최초 1회만 실행되고 그 이후에는 실행되지 않음
useEffect(function () {
console.log("function => useEffect (componentDidMount)")
// effect이후 clean up 작업
return function () {
// 컴포넌트가 삭제될 때 실행
console.log("function => useEffect return (componentWillUnMount)")
}
}, [])
// 두번째 인자로 전달된 배열에 number가 있음
// number의 상태가 바뀌면 첫 번째 인자인 함수가 호출됨
// side effect(부가적인 작용)
useEffect(
function () {
console.log("function => useEffect number(componentDidMount & componentDidUpdate)")
return function () {
console.log("function => useEffect number return (componentDidMount, componentDidUpdate & componentWillUnmount)")
}
},
[number]
)
console.log("function => render")
return (...)
}
- hook의
useEffect
사용 useEffect
는componentDidMount
,componentDidUpdate
,componentWillUnmount
가 합쳐진 것으로 생각할 수 있음useEffect
가return 하는
함수는 clean up(정리)의 역할을 가짐. 어떤 작업을 한 이후 뒤처리 작업이라고 생각할 수 있음.
실행 예시
- 컴포넌트 생성
Mount component - state 변경
ClassComp의 상태 업데이트 FuncComp의 number 상태 업데이트 - 컴포넌트 삭제
ClassComp 삭제 FuncComp 삭제
참고 사이트
댓글