2019-08-05
리액트 라이프사이클 메서드 특히 shouldComponentUpdate 나 componentWillReceiveProps는 외부에서 state나 props를 변경할 때만 호출된다고 생각했는데
외부가 아닌 내부에서 state가 변해도 실행된다.
componentWillReceiveProps는 mount시점에는 실행되지 않고, props가 변하지 않더라도, 부모가 재 렌더되면 실행된다.
테스트시 부모의 내부 state 변화(setTimeout으로 setState수행. 외부에서 내려온 변화 없음)에 의해 재 렌더 되었고, 이에 따라 자식 컴포넌트 역시 재 렌더되었다.
constructor!
render!
NESTED] constructor!
NESTED] render!
NESTED] componentDidMount!
componentDidMount!
--- 부모의 내부 state변화 ---
shouldComponentUpdate!
render!
NESTED] componentWillReceiveProps! Object {props: true} Object {}
NESTED] shouldComponentUpdate! Object {props: true} Object {nested: "a"}
NESTED] render!
그런데!!!!!
componentWillReceiveProps
는 리액트 17부터는 삭제될 예정이다.
정확히는 componentWillMount
componentWillReceiveProps
componentWillUpdate
세 개가 다음과 같은 순서로 제거된다.
UNSAFE_componentWillMount
, UNSAFE_componentWillReceiveProps
, UNSAFE_componentWillUpdate
(UNSAFE_ 안붙은 메서드도 유지)componentWillMount
, componentWillReceiveProps
, componentWillUpdate
.
(이전 버전과 같지만 dev모드에서 deprecate warning 표출)componentWillMount
, componentWillReceiveProps
, componentWillUpdate
(이 시점 부터는 UNSAFE_ 붙은 메서드만 유지)출처: 한재엽님 블로그
props
가 변경되지 않아도 componentWillReceiveProps
는 실행하기 때문에 this.props
와 nextProps
를 비교하는 것이 중요합니다.componentWillReceiveProps
은 해당 컴포넌트가 mounted 되기 전에 실행되어 새로운 props
를 받습니다. 이것은 React가 mount 중에는 초기 props에 대해 componentWillReceiveProps
를 호출하지 않는다는 것을 의미합니다.React version 16에서 componentWillReceiveProps
를 사용하여 상태를 변경할 때는 동기적으로업데이트 해야 합니다.(dispatch request 또는 setTimeout
과 같은 비동기적 요청은 해당 메소드에서 처리하면 안 됩니다.)
React Fiber 를 사용하면 라이프 사이클이 진행되기 전에 componentWill[*]
메서드가 여러 번 호출 될 수 있습니다. props
이 변경될 때 상태를 비동기적으로 업데이트하려면 componentDidUpdate
를 사용해야 합니다.
최신 라이프사이클
출처: 공식문서
Mounting
Updating
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
Unmounting
이 다이어그램도 있다. (구글에 react lifecyle 치면 이미지에 늘 나오는 그것)
constructor
: Function components don’t need a constructor. You can initialize the state in the useState
call. If computing the initial state is expensive, you can pass a function to useState
.
getDerivedStateFromProps
: Schedule an update while rendering instead.
shouldComponentUpdate
: See React.memo
below.
render
: This is the function component body itself.
componentDidMount
, componentDidUpdate
, componentWillUnmount
: The useEffect
Hook can express all combinations of these (including less common cases). => 다이어그램에서 이 세 라이프사이클 메서드이 모두 side effect를 실행하는 역할을 한다는 것과 연관되는 네이밍이다!
componentDidCatch
and getDerivedStateFromError
: There are no Hook equivalents for these methods yet, but they will be added soon.
Hooks와 기존 라이프사이클이 완전히 대응되는 것인지는 모르겠다. 대응 될 필요가 있는걸까? 라이프사이클 메서드 개념에서 벗어나야 하는걸까? Hooks는 과연 기존 라이프사이클 메서드를 엮어서 만든것일까?
이제부터는 Hooks를 파헤쳐보자