생명주기 메서드는 리액트의 클래스 컴포넌트에서만 사용이 가능합니다.
함수 컴포넌트에서는 useEffect()라는 리액트 훅을 이용하여 유사한 기능을 구현할 수 있습니다.
생명주기 메서드는 다음 세 가지의 경우에서 자동으로 호출되는 메서드를 말합니다.
컴포넌트가 생성될 때 호출되는 생명주기 메서드입니다.
생성자에서는 반드시 super(props)를 호출해야 하며, 이를 호출하지 않으면 컴포넌트에서 props를 사용할 수 없습니다.
생성자는 this.state에 객체를 할당하여 컴포넌트의 상태를 초기화하기 위해 작성합니다.
생성자 내부에서는 초기화만 가능하며 this.setState() 메서드를 이용하여 상태를 변경하면 안됩니다.
만약 상태를 초기화할 일이 없다면 생성자를 작성하지 않아도 됩니다.
constructor(props) {
this.state = {name: "홍길동", age: 20}
}
타입스크립트 언어에서는 constructor를 사용하면 this.state 속성의 타입을 지정할 수 없습니다.
따라서 constructor를 사용하더라도 any 타입을 사용해야 하므로 권장하지 않습니다.
대신 클래스 내의 state 인스턴스 멤버를 지정하는 방법을 사용합니다.
type StateType = {
name: string;
age: number;
}
export default class Test extends Component<{}, StateType> {
state : StateType = {naem: "홍길동", age: 20}
render() {
const {name, age} = this.state
return <div> {name}님의 나이 : {age} </div>
}
}
이는 props와 state에 해당하는 두 개의 인자를 전달받습니다.
props는 전달받은 속성 객체이며 state는 컴포넌트의 기존 상태입니다.
props를 이용하여 새로운 상태를 만들고 이를 리턴합니다.
type Props = { level: string }
type State = { discountRate: number ; customerName: string }
export default class Child extends Component<Props, State> {
state: State = { discountRate:0, customerName: "홍길동"};
static getDerivedStateFromProps(props: Props, state: State){
let tempRate = 0
if (props.level === "GOLD") tempRate = 0.15
else if (props.level === "SILVER") tempRate = 0.1
else if (props.level === "BRONZE") tempRate = 0.05
else tempRate = 0.02
return {...state, discountRate: tempRate}
}
render() {
return(
<div>
{this.state.customerName} 님의 할인율은 {this.state.discountRate * 100}% 입니다.
</div>
)
}
}
렌더링 성능을 최적화할 때 자주 사용됩니다.
해당 메서드에 전달되는 인자는 새롭게 전달된 nextProps, nextState 입니다.
리턴값은 boolean 형식입니다.
해당 메서드에서는 새롭게 전달된 속성과 상태를 기존의 속성인 this.props와 상태인 this.state와 비교하여 다시 렌더링할지를 결정합니다.
shouldComponentUpdate(nextProps: props, nextState: State) : boolean {
}
깊은 비교를 수행하는 경우에는 많은 시스템 리소스가 사용되므로 렌더링 성능의 최적화가 어렵습니다.
render() 메서드가 호출되어 가상 DOM으로의 쓰기 작업이 완료된 후, 브라우저 DOM에 업데이트가 되기 전에 실행됩니다.
변경 전의 DOM 상태 정보를 획득하여 스냅샷 값으로 리턴하여 componentDidUpdate() 메서드의 세 번째 인자로 받아낼 때 사용합니다.
getSnapshotBeforeUpdate(prevProps, prevState) {
return
}
브라우저 DOM까지 업데이트가 완료된 이후에 해당 메서드가 실행됩니다.
해당 메서드는 컴포넌트가 업데이트되고 DOM을 변경하고자 할 때 사용합니다.
현재의 속성과 상태인 this.props, this.state를 이전의 속성, 상태와 비교하여 차이가 있다면 외부 API를 요청하는 등의 작업을 수행하도록 활용할 수 있습니다.
componentDidUpdate(prevProps, prevState, snapshot){
}
가상 DOM을 사용하는 이유는 브라우저 DOM을 조작하는 것이 느리기 때문입니다.
이 중에서 화면에 그려내는 작업이 느립니다.
브라우저의 화면은 reflow와 repaint 두 단계를 거쳐서 렌더링됩니다.
key 특성은 컴포넌트 내부에서 반복적으로 자식 컴포넌트와 요소를 렌더링할 때 지정합니다.
일부 항목들이 추가 삭제 변경되는 경우에 변경 사항을 추적하는 것은 쉽지 않기 때문에 이를 추적하기 위해 key 특성을 사용합니다.
key를 지정하지 않으면 배열 데이터의 어떤 값이 어느 요소에 렌더링됐는지를 추적할 방법이 없습니다.
shouldComponentUpdate 생명주기 메서드는 컴포넌트의 render 메서드가 호출되기 전에 실행됩니다.
렌더링 여부를 빠르게 결정하기 위해서는 불변성을 가진 상태 변경이 필요합니다.
리액트이 렌더링 최적화를 위해 가장 기본적으로 필요한 요구 사항은 불변성을 가지도록 상태를 변경하는 것입니다.