라이프사이클 메서드 사용

Posted by yunki kim on June 29, 2021

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//App.js
import logo from './logo.svg';
import './App.css';
import React, {Component} from 'react';
import LifeCycle from "./life_cycle";
import ErrorBoundary from "./error_boundary";
 
//랜덤 색생 생성
function getRandomColor() {
  return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}
 
class App extends Component {
  state = {
    color: '#000000'
  }
 
  handleClick = () => {
    this.setState({
      color: getRandomColor()
    });
  }
 
  render() {
    return (
        <div>
          <button onClick={this.handleClick}>Random color</button>
          <ErrorBoundary>
            <LifeCycle color={this.state.color}/>
          </ErrorBoundary>
        </div>
    )
  }
}
 
export default App;
 
 
//LifeCycle.js
import React, {Component} from 'react';
 
class LifeCycle extends Component {
    state = {
        number: 0,
        color: null,
    }
 
    myRef = null;//ref 설정
 
    constructor(props) {
        super(props);
        console.log('constructor');
    }
 
    static getDerivedStateFromProps(nextProps, prevState){
        console.log('getDerivedStateFromProps');
        if(nextProps.color !== prevState.color){
            return {color: nextProps.color};
        }
        return null;
    }
 
    componentDidMount(){
        console.log('componentDidMount');
    }
 
    shouldComponentUpdate(nextProps, nextState){
        console.log('shouldComponentUpdate', nextProps, nextState);
        return nextState.number % 10 !== 4;
    }
 
    componentWillUnmount() {
        console.log('componentWillUnmount');
    }
 
    handleClick = () => {
        this.setState({
            number: this.state.number + 1
        });
    }
 
    getSnapshotBeforeUpdate(prevProps, prevState){
        console.log('getSnapshotBeforeUpdate');
        if(prevProps.color !== this.props.color){
            return this.myRef.style.color;
        }
        return null;
    }
 
    componentDidUpdate(prevProps, prevState, snapshot){
        console.log('componentDidUpdate', prevProps, prevState);
        if(snapshot){
            console.log('Previous color: ', snapshot);
        }
    }
 
    render() {
        console.log('render');
        const style = {
            color: this.props.color,
        }
        return (
            <div>
                {this.props.missing.value}
                <h1 style={style} ref={ref => this.myRef=ref}>
                    {this.state.number}
                </h1>
                <p>color: {this.state.color}</p>
                <button onClick={this.handleClick}>
                    add
                </button>
            </div>
        )
    }
}
 
export default LifeCycle;
cs

결과:

에러 처리

  위 코드에서 존재하지 않는 props를 하나 추가해 에러를 내보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, {Component} from 'react';
 
class LifeCycle extends Component {
    //.......
    render() {
       //....
        return (
            <div>
                {this.props.missing.value}
                //......
            </div>
        )
    }
}
 
export default LifeCycle;
cs

이러면 TypeError: Cannot read property 'value' of undefined라는 에러창이 뜬다. 이는 개발 서버이기 때문이고 배포를 한다면 휜페이지만 보일것이다. 따라서 에러를 잡아주는 컴포넌트가 필요하다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//ErrorBoundary.js
import React, {Component} from 'react';
 
class ErrorBoundary extends Component {
    state = {
        error: false
    };
    componentDidCatch(error, errorInfo) {
        this.setState({
            error: true
        });
        console.log({error, info});
    }
    render() {
        if(this.state.eror) return <div>Error occurred</div>
        return this.props.children;
    }
}
 
export default ErrorBoundary;
 
//App.js
//...
import ErrorBoundary from "./error_boundary";
class App extends Component {
  //...
  
  render() {
    return (
        <div>
          <button onClick={this.handleClick}>Random color</button>
          <ErrorBoundary>
            <LifeCycle color={this.state.color}/>
          </ErrorBoundary>
        </div>
    )
  }
}
cs

위와 같이 에러 처리를 해주면 휜 화면 대신 다음과 같은 결과가 나온다