React - LifeCycle API
LifeCycle API
생명주기.
Component가
- 나타날 때
- 업데이트 될 때
- 사라질 때
중간중간에서 사용하고 싶을 때 사용한다.
종류가 많다.
constructor -> render -> 등등,,, 하나하나가 다 함수이다.
Mounting
브라우저 상에 나타날 때.
constructor : 만들어질 때 가장 처음 됨. state
getDerivedStateFromProps
render
componentDidMount : 외부 라이브러리에서 특정 DOM에 그려달라, API 요청같은거 할 때? 우리가 만든 컴포넌트가 브라우저에 나타난 시점에 어떤걸 하냐.
Updating
getDerivedStateFromProps
shouldComponentUpdate : 렌더링 작업이 불필요해질 때(업데이트 된 것만 바뀌어야 한다.) Virtual DOM에 그리는 것도 아끼기 위해. true나 false 값 반환.true이면 렌더링 하고 false이면 렌더링 안한다.
render
getSnapshotBeforeUpdate : 브라우저에 반영되기 직전에 호출되는 거.
componentDidUpdate : 작업을 마치고 업데이트 되었을 떄 호출. 이전의 상태와 지금의 상태가 바뀌었을 때 사용 등등
Unmounting
componentWillUnmount : 설정한 리스너 없애기
브라우저 상에서 사라질 때.
2.
컴포넌트 초기 생성
컴포넌트가 브라우저에 나타나기 전, 후에 호출되는 API가 있다.
constructor
constructor(props){
super(props);
}
componentDidMount
componentDidMount(){
//외부 라이브러리 연동 : D3, masonry, etc
//컴포넌트에서 필요한 데이터 요청: Ajax, GraphQL, etc
//DOM에 관련된 작업 : 스크롤 설정, 크기 읽어오기 등
}
컴포넌트가 화면에 나타나게 됐을 때 호출된다.
컴포넌트 업데이트
getDerivedStateFromProps()
static getDerivedStateFromProps(nextProps, prevState){
//여기서는 setState를 하는 것이 아니라 특정 props가 바뀔 때 설정하고 싶은 state 값을 리턴하는 형태로 사용.
/*
if(nextProps.value !== prevState.value){
return{ value: nextProps.value };
}
return null; //null을 리턴하면 따로 업데이트 할 것은 없다라는 의미
*/
}
shouldComponenetUpdate
shouldComponentUpdate(nextProps, nextState){
//return false 하면 업데이트를 안함
// return this.props.checked !==nextProps.checked
return true; //업데이트를 함.
}
컴포넌트를 최적화하는 작업을 할 때 유용하다. 리액트에서는 변화가 발생하는 부분만 업데이틀 해줘서 성능이 좋은데, 변화가 발생한 부분만 감지해내기 위해서는 Virtual Dom에 그려줘야 한다.
현재 컴포넌트의 상태가 업데이트 되지 않아도, 부모 컴포넌트가 리렌더링 되면, 자식 컴포넌트들도 렌더링된다. 이 “렌더링”된다는 것은 render()함수를 호출한다는 뜻이다.
getSnapshotBeforeUpdate()
이 API가 발생하는 시점은
render()가 되고 난 후, 실제 DOM에 변화 발생 전이다.
DOM 변화가 일어나기 직전의 DOM 상태를 가져오고, 리턴하는 값은 componentDidUpdate의 3번쨰 파라미터로 받아올 수 있다.
getSnapshotBeforeUpdate(prevProps, prevState){
//
}
componentWillUnmount
componentWillUnmount() {
console.log('Good Bye');
}
해당 컴포넌트가 없어질 때 실행된다.
componentDidCatch
원래는 render 함수에서 에러가 발생하면 리액트 앱이 crash 된다. 이때 이걸 사용하면 된다.
componentDidCatch(error, info){
//error는 무슨 에러가 났는지 확인할 수 있다.
this.setState({
error : true
})
}
에러가 발생할 수 있는 컴포넌트의 부모 컴포넌트에서 사용해야 한다.
App.js
import React, { Component } from 'react';
import MyComponent from './MyComponent';
class App extends Component {
state = {
counter: 1
};
constructor(props) {
super(props); //Component를 상속하는데 컴포넌트의 생성자를 먼저 호출해주는 거.
console.log('constructor');
}
componentDidMount() {
console.log('componentDidMount');
}
handleClick = () => {
this.setState({
counter: this.state.counter + 1
});
};
render() {
return (
<div>
{this.state.counter < 10 && <MyComponent value={this.state.counter} />}
<button onClick={this.handleClick}>Click Me</button>
</div>
);
}
}
export default App;
MyComponent.js
import React, { Component } from 'react';
class MyComponent extends Component {
state = {
value: 0
};
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.value !== nextProps.value) {
return {
value: nextProps.value
};
}
return null;
}
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.value === 10) return false;
return true;
}
componentDidUpdate(prevProps, prevState) {
if (this.props.value !== prevProps.value) {
console.log('value 값이 바뀌었다!', this.props.value);
}
}
componentWillUnmount() {
console.log('Good Bye');
}
render() {
return (
<div>
{/*this.props.missing.something */}
<p>props: {this.props.value}</p>
<p>state: {this.state.value}</p>
</div>
);
}
}
export default MyComponent;