안드로이드 앱을 만들어보신 분이라면 라이프사이클을 다들 들어보셨을 겁니다.
벌써 가물가물한데.. onCreate()
나 onStart()
같은 메소드들이 등장하죠.
리액트도 똑같습니다. 정확히는 안드로이드는 App
에 대한 라이프사이클입니다. 앱에 달려있는 여러가지 구조들(toolbox
, navigation bar
등등)의 생명주기가 아닙니다. 그러나 리액트의 생명주기는 Component
에 대한 라이프사이클 입니다. 즉, 화면에 띄우는 여러가지 컴포넌트들의 각각의 생명주기에 동작하는 기능을 다룰 수 있다는 얘기입니다.
리액트를 공부하시는 분들은 클래스형 컴포넌트
와 함수형 컴포넌트
를 알고 계실 겁니다.
요즘은 리액트 개발진도 함수형 컴포넌트
사용을 권장하고 있죠.
과거에는 상태를 다룰 수 없다는 치명적 단점때문에 클래스형 컴포넌트
를 사용했지만, Hooks
의 등장으로 모든 것이 바뀌었죠.
말이 길어졌는데, 이 생명주기 메소드들은 클래스형 컴포넌트
에서 밖에 사용할 수 없습니다. Hooks
를 사용해 함수형 컴포넌트
에서도 비슷한 작업을 처리할 수 있지만, 이게 생명주기 메소드를 의미하는 것은 아닙니다.
메소드는 총 9가지로 이뤄져있는데, 한번 나열해보겠습니다.
1. Constructor
2. getDerivedStateFromProps => 임의메소드 정의시 static 붙여서 사용
3. render
4. componentDidMount
5. shouldComponentUpdate
6. componentWillUnmount
7. getSnapshotBeforeUpdate
8. componentDidUpdate
9. componentDidCatch
이는 그냥 props
를 사용하거나 state
를 정의하기 위해 쓰는 constructor
인데요. 초기 state
를 설정하는데 쓰이는 생성자입니다. 컴포넌트를 만들 때 최초로 실행됩니다.
State
는 모두들 아시겠지만, 현재 컴포넌트의 상태를 말합니다.
그리고 props
는 부모 컴포넌트로부터 받아오는 값들입니다.
그런데, 이 props
값을 간혹가다, state
안에 넣어주는 경우가 있습니다.
즉, 다시 말해서 부모로부터 오는 값인 props
를 현재 상태 state
에 넣는겁니다.
그렇다는 것은, update
마다 이 props
값을 state
에 넣어줘야겠죠?
그 동기화를 수행해줍니다.
가장 중요한 라이프사이클 메소드로 유일하게 필수인 메소드 입니다.
컴포넌트의 모양새를 정의하고, props, state
를 접근하며, 리액트 요소를 반환합니다. 흔히 JSX
코드를 반환하는데, 그 외에도 null
이나 false
, 따로 선언한 Component
를 반환할 수도 있죠.
주의할 점은 DOM
정보나 state
변화 등은 render에서 하면 안 된다는 것입니다.
render
를 해야, DOM
이 생성되고 화면이 그려지기 때문에, render
시점에서 DOM
정보를 얻어올 수가 없습니다. DOM
정보 참고는 componentDidMount
즉, 마운트가 끝난 시점에서 해야합니다.
Mount
는 DOM
이 생성되고 웹 브라우저 상에서 나타나는 것을 말합니다. 이때부터는 DOM
정보를 참고할 수 있게 됩니다.
첫 렌더링이 끝난 후, 실행하는 메소드입니다.
이벤트 등록, 비동기 작업(네트워크, setTimeout, setInterval)등을 여기서 처리합니다.
반드시 참 또는 거짓을 반환해야 하는 메소드인데, 리렌더링을 할지말지에 대한 여부를 결정하는 메소드로, 최적화에 관여하는 메소드 입니다. 리렌더링을 많이할수록 최적화로부터 멀어지기 때문이죠.
현재 props와 state는 this.props
, this.state
로 접근하고, 매개변수로는 nextProps
, nextState
를 사용함으로써 새로 설정될 값에 접근할 수 있습니다.
render에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출됩니다.(리렌더링 직전)
여기서 반환되는 값은 ComponentDidUpdate에서 3번째 매개변수로 사용됩니다.
업데이트 직전값을 참고하고 싶을 때 사용합니다.
리렌더링이 완료된 후 실행되는데, 매개변수로는 (prevProps, prevState, snapshot)
가 있어서 총 3개를 가집니다. 컴포넌트가 이전에 가졌던 데이터에 접근하는 앞의 두 개, 그리고 6번 메소드로부터 반환된 snapshot까지 총 3개지요.
DOM
에서 컴포넌트를 제거할 때 실행합니다. componentDidMount
에서 등록해놨던 비동기 작업, 이벤트, 새로 생성한 DOM
등이 있을 때 여기서 제거합니다.
다른 것들보다 비교적 나중에 만들어진 것으로, 오류에 대해 보여줍니다.
출처 : https://user-images.githubusercontent.com/6733004/45587740-f8ed0e00-b944-11e8-9c99-7baab37944e8.jpg
순서도는 위와 같은데 마운트할 때는 총 4개를 사용합니다.
실제적으로 DOM이 보여지는 부분은 render 와 DidMount 사이이구요.
업데이트(리렌더링) 경우는 총 5개를 사용하고, 실제로 리렌더링이 이루어지는 부분은 스냅샷과 DidUpdate 사이입니다. 물론 snapshot을 사용하지 않는다면 render와 DidUpdate 사이겠죠.
마지막으로 언마운트의 경우는 WillUnmount만 사용합니다.
어차피, 이미 마운트가 끝나 컴포넌트가 있는 상태니, 따로 뭘 더 해줄게 없으니까요.
이렇게 라이프사이클에 대해서 알아봤는데,
역시 본인이 실습을 해보는게 가장 중요할 것 같습니다.
라이프사이클 메소드는 제가 알기론 Hooks로는 다룰 수 없는 부분까지 다루는 것으로 알고 있는데, 때문에 함수형 컴포넌트외에 이 부분을 반드시 익혀놔야 리액트 고수가 될 수 있을 것 같네요.