만약 다음과 같은 코드가 있다고 가정하면, React Fiber는 stateNode를 통해 new Component가 저장된다. 이후 인스턴스의 render 메서드를 호출해 가상DOM을 얻는다. 즉 render 메서드가 호출되면, Hello에 대한 Fiber가 생성된다. 그 다음 beginWork()가 호출된 후 인스턴스화가 발생한다.
🤔 근데 왜 리액트 내부에서 인스턴스를 할까 유저가 하면 안되는걸까 - 이유는 인스턴스를 활용해 지속성을 보장했다고 한다. 참조하고 있으면 데이터가 가비지 컬렉터가 수거해가지 않기 때문이다. React가 클래스형 컴포넌트를 인스턴스화하는 이유는, 생성된 인스턴스를 Fiber 트리가 stateNode로 참조함으로써 객체의 지속성(persistence) 을 유지하고, 이를 통해 컴포넌트의 상태(state) 와 생명주기(lifecycle) 를안정적으로 관리하기 위함이다
클래스 컴포넌트 생명주기
클래스형 컴포넌트에서 생명주기 메서드는 참 많이 언급된다.
근데 그 이유를 대강 알아차렸다. 리액트가 인스턴스의 지속성을 보장하기 때문에 라는 생각이 들었다.
그래서 어떤 렌더링이 일어나도 항상 같은 객체를 가르키게 되어 생명주기 메서드로 이를 관리하기 위해 만들었다는 생각이 들었다.
생명주기 메서드는 크게 3가지가 있다.
Mount, Update, Unmount가 있다
Mount
컴포넌트가 생성되는 시점
componentDidMount
Update
이미 생성된 컴포넌트의 내용이 변경되는 시점
componentDidUpdate
Unmount
컴포넌트가 더이상 존재하지 않는 시점
componentWillUnmount
차례대로 살펴보자 Mount - React가 인스턴스를 생성하고, constructor -> render 순으로 호출한 후, DOM에 실제 요소를 붙이면 componentDidMount()가 호출 된다.
Update - props가 바뀌거나 setState또는 forceUpdate가 호출되면, 동일한 인스턴스 유지한 후 render를 실행하고, DOM을 갱신 한 후 componentDidUpdate가 호출된다
Unmount - React가 컴포넌트에서 트리를 제거하면, 실제 DOM에서 제거되지 전에 componentWilUnmount를 호출한다.
근데 생각해보자 리액트 파이버는 렌더 단계에서 비동기 처리로 하는데 클래스형 컴포넌트의 경우 트러블이 생길 수 있다.
리액트 공식문서를 참고했다. 렌더 단계의 라이프사이클 메서드들이 비동기 처리를 할 때 버그들이 생길 수 있다고 한다. 이러한 위험성이 있기 때문에 리액트는 함수형 컴포넌트로 바꾼 근거가 되지 않을까 생각이 들었다.
또 다른 이유는 상태와 생명주기가 인스턴스에 종속이 되어있다는 것이다. 리액트는 하나의 컴포넌트를 객체화를 인스턴스화를 해야만 상태와 생명주기를 추적할 수 있기 때문에 문제가 생긴다. -> 이는 생명주기를 직접관리해야 하는 수고로움이 생길 수 있고, 중단 / 재개 등이 어려울 수 있다.