[TIL]리액트 기초 (렌더링의 원리,useState 캐치 )

이명진·2022년 12월 22일
0

TIL

목록 보기
4/16

서두

면접을 보러다니다가 기술면접에서 원리에 관해서 질문을 듣게 되었다.
리액트.. 자주 사용하고 어떻게 쓰는지 알고 훅도 사용해서 useState, useEffect를 이제는
눈감고도 쓸수 있을 정도로 많이 썼다고 생각했는데

‘리엑트 렌더링이 되는 원리, useState가 캐치되고 컴포넌트가 리렌더링 되는 원리에 대해 설명해보세요’ 에 말문이 딱 막혔다.

머리로는 어떻게 사용할지 그려지긴했지만 이것을 어떻게 설명해야 할지 감도 잡히지 않았다.
이외에도 라우터의 원리 등 원리에 대한 질문들이 많았었는데

자주 사용해서 익숙해진 녀석들인데 원리에 대해서는 생각안하고 그냥 무턱대고 썼던 것이
면접에서 말도 꺼낼수 없게 만들었다.

리액트를 많이 사용해왔고 어떻게 사용해야 하는지 알고있는데.. 여기서 막히다니 리액트를 사용 못하는 것처럼 보여서 억울하기도했고 나의 이력서의 리액트 사용에 대한 내용들이 부정당하는 느낌이었다..

생각해보니 원리도 모르고 사용만 한것에 대해 리액트에 대해 미안하기도 하여 간단하게 원리에대해 다시 공부하게 되었고 이렇게 정리하게 되었다.

렌더링 이란 ?

컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업을 의미한다.

렌더링 프로세스

렌더링이 일어나는 동안, 리액트는 컴포넌트 루트부터 시작하여 쭉 훑어보면서 , 업데이트가 필요하다고 플래그가 지정되어 있는 모든 컴포넌트를 찾는다. 플래그 컴포넌트를 찾으면 클래스 컴포넌트의 경우 ‘classComponentInstance.render()’를, 함수형은 ‘FunctionComponent()’를 호출하고 렌더링 결과를 저장한다.

리액트는 새로운 오브젝트 트리와 비교하여 실제 DOM을 의도한 출력처럼 보이게 적용해야 하는 모든 변경 사항을 수집한다. (가상돔으로 달라진 부분만 캐치하는 방법)

일반적인 렌더링 동작

리액트는 부모 컴포넌트가 렌더링 되면 , 모든 자식 컴포넌트를 순차적으로 리렌더링 한다.

부모가 값이 변경되어 렌더링 되면 자식들은 변경되지 않았어도 순차적으로 자식들도 리렌더링 된다.

기본적으로 렌더링은 DOM을 업데이트 하는 것과 같은게 아니고 어떠한 가시적인 변경이 없이도 컴포넌트가 렌더링 될수 있다는 것이다. 결과물이 같다면 아무런 변화가 일어나지 않을수있다.

이외에도 심화된 렌더링에 관한 내용이 있었는데 한번에 이해가 되지는 않았다.. 이해되는 선에서 정리를 해보았다. 나머지는 나중에 다시 공부하다보면 익혀질것이라 믿는다.

useState 동작

const MyReact = (function () {
    let _states = [];
    let idx = 0;

    function useState(initialValue) {
        const state = _states[idx] || initialValue;
        const currIdx = idx;  

        function setState(value) {
            _states[currIdx] = value;
        }

        idx += 1;  
        return [state, setState];
    }

    function render(Component) {
        idx = 0;  
        return Component();
    }

    return { useState, render };
})();

위 코드의 MyReact는 useState와 비슷한 동작으로 새로 작성한 함수이다.
최종 코드이고 어떻게 이코드가 나왔는지에 대해서는 아래 출처에 따로 적겠다.
훅을 사용하기 위해 어딘가에 지정된 useState함수를 가져왔을 것이다.

Const [count,setCount] = MyReaact.useState(1) 

형식으로 사용하면 될것이다.
구조분해 할당을 통해 state와 setState 이름을 변경해줘서 count,setCount로 사용이 가능하다.
함수가 실행되고 컴포넌트가 리렌더링 되는 이유는 function render 함수가 실행되서
리렌더링 또한 가능한 원리로 생각이 된다.

위의 코드도 참고를 한것인데 완벽한 함수는 아니다. 기존 useState는 각자의 고유 키값을 가지고
setState를 할때마다 그 키의 값을 변경시키고 알려주고 할것이다. 또한 확장되서 여러 컴포넌트들의 데이터를 저장할것이다. 기본적인 원리만 알아두도록 하자.

useState값 캐치

리액트는 애플리케이션에 존재하는 모든 현재 컴포넌트 인스턴스를 추적하는 내부 데이터 구조를 가지고 있다.
FIber라는 객체가 있는데 실제 컴포넌트 Props와 state값을 저장하고 있다.
여기서 인스턴스를 추적하기 때문에 useState값을 캐치 해내는것같다.
이해한 바로는 이렇게 인데 만약 다른 정보라면 태클 부탁드립니다.

요약

확실히 공부를 해도 아직까지는 와닿지는 않는다.. 위의 질문

‘리엑트 렌더링이 되는 원리, useState가 캐치되고 컴포넌트가 리렌더링 되는 원리에 대해 설명해보세요’
의 답변에서

리엑트 렌더링이 되는 원리

기본적으로 리엑트는 JSX문법으로 되어 있고 js로 컴파일되고 배포준비가 되는순간에 createElement를 호출하여 변환되는데 JS객체인 React Element를 리턴하면서 초기 렌더가 진행되고 이후에는 렌더링 과정중에 업데이트가 필요하다고 여겨진 플래그 가 지정된곳을 쭉 훑어보면서 가상돔으로 비교를 해보고 변경되어서 리렌더링이 일어나는것 같다.

useState 가 캐치되고 컴포넌트가 리렌더링 되는 원리

FIber라는 객체가 있는데 실제 컴포넌트 Props와 state값을 저장하고 있다.
Flber라는 인스턴스에서 useState값을 캐치해내고 리렌더링이 일어난다
useState함수에서 setState함수를 실행하면서 render라는 함수를 재 호출해 함수를 리렌더링 하는 것 같다.

후기

완벽한 답은 아닌것 같다. 공부를 해봐도 어려운것 같다. 간략하게 정리해봤는데 정답인지 아닌지 확실히 모르겠다.. 나중에 다시 공부해볼 기회가 있으면 수정해보도록 하겠다.

출처

리액트의 렌더링은 어떻게 일어나는가?
Hook동작 원리 간단히 알아보자

profile
프론트엔드 개발자 초보에서 고수까지!

0개의 댓글