(출처 : 대한민국 법제처)
거지와 노예를 반복하는 인간의 인생처럼 리액트에도 Life Cycle이 존재한다! 지금부터 리액트세상에서의 라이프사이클이 무엇인지 알아보도록 하자!
Life cycle
컴포넌트가 생성되서 사용되고 소멸될때까지의 과정을 Life Cycle이라고 한다. 아래의 그림을 한번 살펴보면 크게 세 단계로 나눌수 있는데.. (출처 :http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)
Mount (초기화 단계)
컴포넌트가 처음 실행될 때
constructor → getDerivedStateFromProps → render → componentDidMount
순으로 작동!
constructor
- 컴포넌트가 처음 생성될 때.
- 여기서 state와 props의 기본값 설정.
- props 넘길때 꼭 super안에 props를 넣어줘야 함!
- this.state 객체를 직접 할당할 수 있는 유일한 곳. 다른 곳에선 this.setState()를 써야함.
static getDerivedStateFromProps(props,state)
- props에 있는 값을 state로 동기화 할 때 씀.
- 시간에 따라 변하는 props로부터 state값을 계산할 때 씀(애니메이션)
- 이걸 이용해 메모이제이션 구현도 가능
- 어떤객체를 넣어주면 state값이 됨. 여기서 메모이제이션이란 이전에 연산한 결과를 저장하고 있는 객체를 사용하는 최적화 기법을 말하는데.. 아직 어렵고 이해 안 가는 부분이라 일단 패쓰!
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.value != prevState.value) {
return { value: nextProps.value };
}
return null;
}
코드는 이러하다.. 그치만 나는 이번 프로젝트에서 props 값을 state로 동기화시킬만한 코드가 없어서 실제로 적용은 못해보았다.
render()
- 컴포넌트가 리액트 세상에 존재함을 알리는 단계! 우리가 작성한 코드를 랜더링함.
- 콘솔도 여기서 찍얼 볼 수 있음. 리턴 다음에 찍을 수 없어~
componentDidMount()
- API 호출할 수 있는 곳
- 이 단계에서 setState를 호출하면 다시 랜더링 됨.
Update (업데이트 단계)
state나 props가 업데이트 되는 단계
getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate
순으로 작동!
위에서 정리한 개념은 패쓰~ 새로운 것들만 개념정리 고고!
shouldComponentUpdate(nextProps, nextState)
- props와 state의 값이 변하면 true, 아니면 false를 리턴함
- true일 경우 render되고, false일 경우 업데이트 중단. 기본값은 true이다!
- 이건 지극히 성능최적화를 위함..
이거 대신 Pure Component를 써도 된다. Pure Component 안에 자동으로 shouldComponentUpdate가 적용이 된다고 한다. 아직 슈컴업도 제대로 이해가 안 된 상태라 이거와 동일한 방식의 퓨어컴포넌트는 일단 Reference에 괜찮은 사이트를 걸어놨다.. 좀 더 공부하다보면 둘 다 뭔지 정확하게 알게 되겠지..
여튼 Home의 자식 컴포넌트인 BestRecipe 컴포넌트에 슈컴업을 적용해보았다.
shouldComponentUpdate(nextProps) {
return nextProps.el !== this.props.el;
}
현재 props의 element와 다음 props의 element가 다르다는 것을 리턴..
화면에 레시피정보가 뜨지 않는걸 보아하니, 업데이트 종료인것이고.. false라는 건데 그럼 현재의 props와 그 다음 props 값이 같다는 건가보다..! 저기서 !==을 ===으로 바꾸면 정상적으로 레시피정보가 뜬다.
그래도 콘솔에 props를 찍어보면 8개나 찍혀서…(하나당 4개씩) 랜더링이 계속 되는거 보면 식을 코드를 잘못 적용한것 같아서 위코드 전용 스택오버플로우에 물어보고있다!
getSnapshotBeforeUpdate(prevProps, prevState)
- 랜더링 한 다음에 그 결과물이 브라우저에 반영되기 직전에 호출됨
- 여기서 반환되는 값은 componentDidUpdate의 세번째 인자로 전달됨.
- 이건 아직까진 잘 안 쓰는 것 같아서 정보가 많이 없다 ㅠㅠ 나중에 쓰게 되면 다시 포스팅 해봐야지!
componentDidUpdate(prevProps, prevState)
- 업데이트 단계의 마지막 메소드!
- 업데이트된 돔의 state를 가장 빠르게 가져올 수 있는 메소드..!
- 컴포넌트 업데이트 이후 DOM을 조작해야 할 때 사용
Unmount (소멸 단계)
componentWillUnmount
- 소멸 단계의 유일무이한 메소드!
- 끝나지 않는 네트워크 요청 취소, 타이머 해제, 구독 해제 등의 작업할 때 쓴다고 한다
이거 약간 어디에 써야할 지 알것 같은데… 예전에 html과 js로 게임 만들기 했을 때 유령이 화면상에선 바닥에 머무르지만, 콘솔창에서의 실제적인 숫자는 계속적으로 증가하는 그런 문제가 있었는데.. 거기에 적용하면 될것 같다! 근데… 지금 리액트로 게임화면 구현하기엔 시간이 벅찰것 같아 생략쓰..☆
Ref
헐 소름… Ref를 한글로 치면 ㄱㄷㄹ.. 내 이니셜이다 ㅋㅋ
- 리액트에서 component나 element의 id 역할을 하는게 바로 Ref
- 작업중인 부모 컴포넌트에서 ref를 통해 자식요소를 쉽게 호출 가능쓰!
- ref 남용 금지! 최대한 state와 props를 이용하는게 유지보수에 좋음
1차 프로젝트에서 어떻게 적용하는지 모르겠어서 제로초님의 강의를 봤다..
input에 focus 효과를 주기 위해
input 태그 안에 ref = {c => { this.input = c; }}
라는 값을 입력하고,
input 태그가 걸린 함수에는 this.input.focus();
라는 함수를 걸어주었다.
이렇게 하면 마우스 입력이 끝나도 focus 깜빡이가 적용이 된다!
일단 명절맞이 라이프사이클 정리는 여기서 이렇게 마치고… 이 부분은 추가적으로 계속 공부하고, 적용해볼 부분을 찾아봐야 이해가 확실히 될것 같다 ㅠㅠ