리액트 전반에 대한 이해

2020. 10. 22. 13:25웹 프론트엔드 깊게 이해하기/리액트 이해하기

리액트는 어떤 과정을 통해 렌더링을 수행하는가?

 

전통적인 방식

자바스크립트를 이용한 전통적인 렌더링 방식은 단순했습니다.문자열로 HTML 을 생성하고 그 안에 Data 가 들어갈 부분을 지정하는 것이었죠. 이렇게 Data 와 HTML 이 조합된 문자열을 브라우저가 받아내서 렌더링하도록 만드는 것이었습니다.

 

하지만 이 전통적인 방식의 문제점은 조금의 변경사항을 반영하고 싶어도 브라우저가 전체를 다시 렌더링하도록 만들 수밖에 없다는 점과 실제로 렌더링 결과물이 바뀌지 않았음에도 새로운 데이터를 받았다는 이유만으로 렌더링이 다시 일어나는 비효율이 발생하는 문제가 있었죠.

 

리액트의 방식

리액트는 이러한 비효율을 줄이기 위해 JSX라는 새로운 파일 형식을 도입했습니다. JSX를 통해 데이터가 들어가야 할 부분을 더 간단한 문법을 통해 지정할 수 있게 만들었고, 조합된 결과물이 바로 렌더링되는 것이 아니라 자바스크립트로 된, 생성해야 할 DOM 구조의 카피본을 만들고(Virtual Dom), 이 카피본을 바탕으로 브라우저가 렌더링을 수행하도록 만들었습니다. 그리고 데이터가 새로 들어왔을 때는, 새로운 카피본을 만들고, 이전의 카피본과 새 카피본을 비교해서 변경된 부분만을 DOM 상에 반영도록 했습니다. 이 비교 작업은 메모리 상에서만 일어나는 일이기 때문에, 브라우저에서는 전혀 영향을 끼치지 않습니다.

 

 

리액트 컴포넌트는 어떤 상황에서 리렌더링 되는가?

  1. 자신의 상태(State) 가 변경될 때
  2. 부모 컴포넌트가 리렌더링될 때
  3. 자신이 전달받은 props가 변경될 때
  4. forceUpdate 함수가 실행될 때

 

 

리액트 컴포넌트의 지역 State 과 Prop

리액트 컴포넌트의 전체 상태(State)는 기본적으로 객체입니다. setState 메서드를 통해 하나의 상태를 변경해도, 얕은 병합이 수행되기 때문에 변경시킬 상태만 갱신시킬 수 있습니다. 이때 setState 메서드는 지역 상태를 비동기적으로 갱신합니다. 그러므로 언제 상태가 변경되는지는 확실히 알 수 없습니다.

대부분의 경우에 이것은 문제가 되지 않지만, 만일 컴포넌트 안에 이전의 상태에 의존하는 연산들이 있다면 어떤 연산은 컴포넌트 상태가 변경되지 않은 상태에서 그냥 수행되어 버리기도 합니다.

 

this.setState({ counter: this.state.counter + 1 }); // this.state: { counter: 0 }
this.setState({ counter: this.state.counter + 1 }); // this.state: { counter: 0 }
this.setState({ counter: this.state.counter + 1 }); // this.state: { counter: 0 }