리액트 컴포넌트는 탄생부터 죽음까지 여러지점에서 개발자가 작업이 가능하도록
메서드를 오버라이딩 할 수 있게 해준다.
constructor - 생성되는 구간
ComponentWillMount - 마운트 되기 직전
render(최초 랜더) - 마운트
componentDidMount - 마운트 된 후
const rootEl = document.querySelector("#root");
class App extends React.Component {
state = {
age: 31
};
constructor(props) {
super(props);
console.log("constructor", props);
}
render() {
console.log("render");
return (
<div>
<h2>
hello {this.props.name} - {this.state.age}
</h2>
</div>
);
}
componentWillMount() {
console.log("componentWillMount");
}
componentDidMount() {
console.log("componentDidMount");
}
}
ReactDOM.render(<App name="kwak" />, rootEl);

여기서 componentDidMount에 setInterval을 준다.
componentDidMount() {
console.log("componentDidMount");
//타이머
setInterval(() => {
//console.log("setInterval");
this.setState((state) => ({ ...state, age: state.age + 1 }));
}, 1000);
}

state가 바뀌면 render가 다시 실행되는걸 알 수 있다.
ComponentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
class App extends React.Component {
state = {
age: 31
};
constructor(props) {
super(props);
console.log("constructor", props);
}
render() {
console.log("render");
return (
<div>
<h2>
hello {this.props.name} - {this.state.age}
</h2>
</div>
);
}
componentWillMount() {
console.log("componentWillMount");
}
componentDidMount() {
console.log("componentDidMount");
//타이머
setInterval(() => {
//console.log("setInterval");
this.setState((state) => ({ ...state, age: state.age + 1 }));
}, 10000);
}
componentWillReceiveProps(nextProps) {
console.log("componentWillReceiveProps", nextProps);
}
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate", nextProps, nextState);
return true;
//return 값이 true이어야 다음으로 넘어간다.
}
componentWillUpdate(nextProps, nextState) {
console.log("componentWillUpdate", nextProps, nextState);
}
componentDidUpdate(prevProps, prevState) {
console.log("componentDidUpdate", prevProps, prevState);
}
}

componentWillUnmount
컴포넌트가 사라지면 interval이 사라질것이다.
interval = null;
componentDidMount() {
console.log("componentDidMount");
//타이머
this.interval = setInterval(() => {
//console.log("setInterval");
this.setState((state) => ({ ...state, age: state.age + 1 }));
}, 2000);
}
componentWillUnMount() {
clearInterval(this.interval);
}
constructor - 생성되는 구간
ComponentWillMount=> getDerivedStateFromProps - 마운트 되기 직전
render(최초 랜더) - 마운트
componentDidMount - 마운트 된 후
ComponentWillReceiveProps=> getDerivedStateFromProps
shouldComponentUpdate
render
componentWillUpdate=> getSnapshotBeforeUpdate (dom에 적용되기 직전)
componentDidUpdate
componentWillUnmount
let i = 0;
class App extends React.Component {
state = { list: [] };
render() {
return (
<div id="list" style={{ height: 100, overflow: "scroll" }}>
{this.state.list.map((i) => {
return <div>{i}</div>;
})}
</div>
);
}
componentDidMount() {
setInterval(() => {
this.setState((state) => ({
list: [...state.list, i++]
}));
}, 5000);
}
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevState.list.length === this.state.list.length) return null;
const list = document.querySelector("#list");
return list.scrollHeight - list.scrollTop;
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(snapshot);
if (snapshot === null) return;
const list = document.querySelector("#list");
list.scrollTop = list.scrollHeight - snapshot;
}

ComponentDidCatch
https://ko.reactjs.org/docs/error-boundaries.html#gatsby-focus-wrapper
class App extends React.Component {
state = {
hasError: false
};
render() {
if (this.state.hasError) {
return <div>예상치 못한 에러가 발생했다.</div>;
}
return <WebService />;
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
}
}
ReactDOM.render(<App />, rootEl);