nika-blog

React 본문

FE/React

React

nika0 2022. 2. 27. 12:56
이 포스팅은 프론트엔드 면접 파트 중 React 대비를 위한 것이며, 아래 내용에 대해 다루고 있습니다. 

- react 개념, 장점, 컴포넌트
- 리액트의 내부 작동 원리
- 리액트에 있는 라이프사이클
- 리액터 라우터같은 Client Side Routing이란?
- setState를 사용하는 이유
- props Drilling
- react Hooks 장점
- Class Component와 Function Component의 차이점
- virtual dom 개념과 장점
- JSX
- 웹 성능 향상을 위해 최적화를 해 본 경험
- react에서 상태 변화가 생겼을 때, 변화를 알아채는 방법?
- 여러가지 상태 관리 라이브러리 차이점
- useEffect 메소드로 componentWillUnmount 동작하기

react 개념, 장점, 컴포넌트

개념

  • UI 구축을 위한 JS 프론트엔드 라이브러리.
  • 주로 SPA 만들 때 사용

장점

  • virtual dom 을 사용해서 어플리케이션 성능 향상.
  • 서버, 클라이언트 사이드 랜더링 지원 가능.
  • 컨포넌트의 가독성이 높고 간단하여 유지보수 쉬움.
  • 다양한 프레임워크와 혼용가능

컴포넌트

  • props를 받아서 state따라 DOM Node 를 출력하느 함수
  • 작은 코드 단위로 만들어 그것들을 조립하듯이 개발
  • 캡슐화, 확장성, 결합성, 재사용성의 이점이 있음

리액트의 내부 작동 원리

  • 동적으로 데이터가 변화했을 때, 직접적으로 dom을 조작하지 않고 가상돔을 그려서 현재 돔 트리와 비교 후 , 변경된 부분만 변경하는 재조정(reconciliation)과정을 거친다. 
  • 이때 virtual dom을 갱신은 setState()로 인해 상태가 변경되었을 때 나타납니다. 
  • 바닐라 JS 에서는 dom 트리를 만든후, 랜더트리를 만들어서 레이아웃, 페인팅 과정을 모두 거친다. 

리액트에 있는 라이프사이클

  • componentDidMount() 는 최초로 컴포넌트 객체가 생성될 때 한 번 수행
  • componentDidUpdate() 는 컴포넌트의 속성 값 또는 상태값이 변경되면 호출
  • componentWillUnmount() 는 이 컴포넌트가 소멸될 때 호출
  • render() 는 초기에 화면에 그려줄 때, 그리고 업데이트가 될 때 호출

리액터 라우터같은 Client Side Routing이란?

  • Client Side Routing은 웹페이지의 랜더링이 클라이언트(브라우저)측에서 일어나는 것. 
    • 서버와 클라이언트 간 데이터 트래픽이 감소하고 렌더링이 한번이라서 페이지 이동이 빠름. 
    • SEO 사용은 불가하며 쿠키에 사용자 정보를 저장해야 해서 위험 요소가 될 수 있음. 
  • 리액터 라우터란 여러 페이지를 보여주고 싶을 때, 클라이언트 사이드 라우팅을 간단하게 도와주는 라이브러리.

setState를 사용하는 이유

  • state는 immutable(불변성)을 유지해야하기 때문입니다.
  • 컴포넌트는 현재의 this.state와 setState를 비교해서 업데이트가 필요한 경우에만 render 함수를 호출하는데 state를 직접 수정하게 되면 리액트가 render 함수를 호출하지 않아 상태 변경이 일어나도 렌더링이 일어나지 않을 수 있습니다.

props Drilling

리액트의 컴포넌트 트리에서 데이터를 전달하기 위해서 필요한 과정을 의미

깊숙히 있는 자손 컴포넌트에 props 전달을 위해서 부모 컨테이너들이 props를 계속해서 전달하는 것 

 

프로퍼티 내리꽂기 (prop drilling)

이 포스트는 Kent C. Dodds의 Prop Drilling을 번역한 글입니다. 이 글에서는 프로퍼티 내리꽂기(prop drilling)를 이해하는데 그치지 않고 어떤 부분이 문제가 될 수 있는지, 이 문제를 피하기 위해 사용할

edykim.com


react Hooks 장점

  • 로직의 재사용이 가능하고 관리가 쉽습니다. 함수 안에서 다른 함수를 호출하는 것으로 새로운 hook을 만들어 볼 수도 있습니다.
  • 기존의 class component 는 여러 단계의 상속으로 인해 전반적으로 복잡성과 오류 가능성을 증가시켰습니다. 하지만 function component에 hooks가 도입되며 class component가 가지고 있는 기능을 모두 사용할 수 있음은 물론이고 기존 class component 복잡성, 재사용성의 단점들까지 해결됩니다.

Class Component와 Function Component의 차이점

  • 선언방식
    (class 컴포넌트는 class 키워드 필요, render()이 필수이며 라이프사이클 메소드 사용가능, 임의 메소드 정의가능, 메모리 자원 함수형보다 많이 사용)

  • state 사용 방식이 다르고
    (클래스형 컴포넌트는 this.state와 this.setState사용, 함수형 컴포넌트는 useState 사용)

  • 이벤트 핸들링 시 this 사용 여부 등에 차이가 있다. 

https://born-dev.tistory.com/27

 

함수형 컴포넌트와 클래스형 컴포넌트의 차이

React 컴포넌트를 만들때 클래스형 컴포넌트, 함수형 컴포넌트 2가지 방식이 있다 과거에는 클래스형 컴포넌트를 많이 사용했지만 2019년 v16.8 부터 함수형 컴포넌트에 리액트 훅(hook)을 지원해 주

born-dev.tistory.com


virtual dom 개념과 장점

  • virtual dom은 리액트에서 성능을 향상시키기 위해 dom 트리와 비교하기 위해 그리는 트리. 
  • virtual dom을 이용하면 작은 변화에도, dom 트리 생성, 랜더 트리 생성, 레이아웃, 리페인트 과정을 거쳐야 했던 브라우저가 HTML 파일을 스크린에 보여줄 때와 달리 변경된 부분만 비교하고 변경할 수 있어서 시간복잡도를 낮출 수 있다. 

JSX?

JSX의 확장 문법으로 React 엘리먼트를 생성하는 언어입니다. 자바스크립트 코드를 HTML처럼 표현할 수 있기 때문에 용이한 개발이 가능합니다

 

웹 성능 향상을 위해 최적화를 해 본 경험

  • useCallback을 이용해서 함수를 기억하게 하고 deps 배열이 변경되었을 때만 함수가 재선언되도록 구현. 
  • React.memo를 이용하여 props가 바뀌지 않았다면 리렌더링 않도록 설정하여 함수형 컴포넌트의 리렌더링 성능을 최적화 해줄 수 있다. 
    예 ) item 컨포넌트를 React.memo로 만들어서  map을 돌려 보여준다면 map을 돌리는 배열의 길이가 변경되었을 때 추가된 item 컨포넌트만 리랜더링 되도록 구현 가능하다. 
  • useMemo를 이용해서 복잡한 계산이 일어나는 값을 계산하지 않고 deps 배열 변경시에만 계산하여 값들을 기억하도록 구현. 

react에서 상태 변화가 생겼을 때, 변화를 알아채는 방법?

React는 상태를 immutable 하게 변경하기 때문에 상태 객체의 주소값이 변경되면 상태가 변화되었다는 것을 알아챌 수 있습니다.


여러가지 상태 관리 라이브러리 차이점

  • Redux
    Flux개념을 바탕으로한 React에서 현재 가장 많이 사용되는 State 관리 라이브러리 입니다.
    **Flux 아키텍처 : 단방향 데이터 흐름 : 디스패치 -> 스토어 -> 뷰 -> 액션 -> 디스패치 ..
  • MobX
    Redux와 또 다른 State관리 라이브러리입니다. 기본적으로 객체지향 느낌이 강하며 Component와 State를 연결하는 코드들을 데코레이터 제공으로 깔끔하게 해결합니다.
  • Apollo
    Redux는 REST API를 사용하기 때문에 리소스의 크기가 서버에서 결정됩니다. 데이터 교환이 복잡하게 이루어지고, 엔드포인트 증가 및 overfetching과 underfetching 등의 문제점을 가지고 있습니다.

    반면에 Apollo Client는 GraphQL을 기반으로 합니다. 서버에서는 어떠한 자원을 사용할 수 있는지 정의하고, 클라이언트에서 렌더링에 필요한 데이터를 요청하는 방식이기 때문에 꼭 필요한 데이터 교환이 이루어지기 때문에 매우 깔끔하며 효과적입니다.

useEffect 메소드로 componentWillUnmount 동작하기

useEffect에 return하는 익명함수를 작성하여 cleanUp 함수 만들기 

useEffect(() => {
    console.log('컴포넌트가 화면에 나타남');
    return () => {
      console.log('컴포넌트가 화면에서 사라짐');
    };
  }, []);