본문 바로가기
우아한 테크코스

생각해보기🤔 - 다시, 점심 뭐 먹지

by 해-온 2023. 6. 19.

 

🍲 React 탄생 배경은 어떻게 될까요?

React는 대규모 웹 애플리케이션 개발에서 발생하는 여러 문제를 해결하고자 하는 것에서 시작되었다. 

특히 UI와 상호 작용하는 데이터의 복잡한 상태 관리와 DOM을 효율적으로 업데이트하는 것이 주요 과제였다.

이를 해결하기 위해 아래 기능을 도입했다.

 

1. 컴포넌트 기반 아키텍처

UI를 독립적이고 재사용 가능한 부분으로 나누어 개발의 복잡성을 줄이고 코드의 유지 보수를 쉽게 했다.

 

2. 가상 DOM (Virtual DOM)

실제 DOM 대신 메모리에 가상의 DOM을 생성한다.

이를 통해 업데이트가 발생할 때 불필요한 DOM 조작을 줄인다.

 

3. 단 방향 데이터 흐름

데이터와 상태가 계층 구조를 따라 일정한 방향으로 흐르게 한다.

이를 통해 상태 관리의 복잡성을 줄이고 안정성을 높인다.

 

 

🍲 JSX와 표현식은 같을까요?

JSX와 표현식은 다르다.

 

1. JSX

JSX는 JavaScript XML의 약자로, React 컴포넌트를 작성할 때 사용하는 문법이다.

JSX는 HTML과 유사하지만 JavaScript 코드 내에 작성하며, 컴포넌트의 구조와 렌더링에 필요한 정보를 제공한다.

 

2. 표현식

표현식은 JavaScript 코드의 일부로, 값을 반환하는 구문이다.

변수, 객체, 배열 등이 표현식이 될 수 있다.

 

 

🍲 JSX와 React.createElement() 는 무슨 관계일까요?

JSX는 JavaScript 코드 내에서 UI를 작성하기 위해 사용되는 컴파일 타임 시점의 문법이다.

React.createElement()는 실제로 런타임에 React 요소를 생성하는 함수이다.

 

JSX 코드는 표준 JavaScript 코드로 변환해야 하는데, 이 변환 과정을 '컴파일'이라고 한다.

컴파일 과정에서 JSX 코드는 React.createElement() 호출로 변환된다.

React.createElement()는 인자로 태그 이름, 속성 객체 등을 받아들이고, 이를 React 요소로 반환한다.

 

 

🍲 document.createElement()와 다른 점은 무엇일까요?

document.createElement()의 경우 HTML DOM 요소를 생성하고, React.createElement()는 React 요소를 생성한다.

차이점은 아래와 같다.

 

1. 생성된 요소의 종류

  • document.createElement()
    • HTML DOM 요소 생성
    • 생성된 요소는 직접 DOM에 추가되거나 수정 가능하며 브라우저에 렌더링 됨
  • React.createElement()
    • React 요소 생성
    • 실제 DOM에 렌더링 되기 전에 다양한 최적화 작업 이루어짐

 

2. 사용된 라이브러리 / 프레임워크

  • document.createElement()
    • 순수한 JavaScript에서 사용 가능
  • React.createElement()
    • React를 사용할 때만 사용

 

3. 작동 방식

  • document.createElement()
    • 새로운 HTML DOM 요소가 즉시 생성
  • React.createElement()
    • React 요소 또는 가상 DOM 요소를 생성
    • 가상 DOM 요소는 JavaScript 객체로 표현되며 렌더링 전에 최적화 작업 수행 후 실제 DOM 요소로 변환됨

 

 

🍲 상태를 직접 변경하지 않고 굳이 setState()를 사용하는 이유가 무엇일까요?

1. 비동기 업데이트

React는 성능 최적화를 위해 상태 업데이트를 일괄 처리하거나 비동기적으로 처리할 수 있다.

setState를 사용해 React가 컴포넌트의 상태 변경 관리 및 성능 향상을 위한 작업을 효율적으로 수행할 수 있다.

 

2. 안정적인 렌더링

setState를 사용하면 React는 내부 상태 변경을 인식한다.

따라서 변경된 상태에 따라 컴포넌트를 다시 렌더링 한다.

 

3. 상태 병합

setState는 현재 상태와 새로운 상태를 병합해 준다.

setState를 사용해 일부 상태만 변경하고 다른 상태를 유지할 수 있다.

 

 

🍲 setState()는 비동기적으로 작동할까요?

setState는 비동기적으로 작동한다.

React에서 setState를 사용하면 상태 변경이 즉시 발생하지 않고, 변경이 예약된다.

그 후 React가 내부적으로 해당 변경사항을 일괄 처리하는 방식으로 작동한다.

여러 setState 호출이 있는 경우, React는 이를 일괄 처리하여 성능을 최적화할 수 있다.

 

 

🍲 불변성을 지켜야 하는 이유는 무엇일까요?

1. 효과적인 상태 업데이트

리액트는 상태값을 업데이트할 때 얕은 비교 통해 이전 상태와 새로운 상태를 빠르게 비교할 수 있다.

이전 참조값과 현재 참조값만을 비교하며 상태 변화를 감지하는 것이다.

불변성을 지키면 쉽게 상태 변경을 감지하고, 필요한 경우에만 컴포넌트를 업데이트 할 수 있다.

 

2. 사이드 이펙트 방지

불변성을 유지하면 원본 데이터를 직접 수정하지 않고 복사본을 만들어 처리한다.

따라서 애플리케이션 전체에서 발생할 수 있는 사이드 이펙트를 줄일 수 있다.

 

 

🍲 bind를 사용해야 하는 이유는 무엇일까요?

JavaScript에서 함수의 this 값은 실행되는 시점에 결정된다.

React 컴포넌트에서 클래스 메서드를 이벤트 핸들러로 사용하는 경우, 해당 메서드를 호출한 객체에 대한 참조가 바뀌어 원래의 컴포넌트 this 값이 바뀔 수 있다.

 

따라서 bind를 사용해야 한다.

bind를 통해 클래스 메서드의 this를 컴포넌트 인스턴스에 고정할 수 있다.

 

 

🍲 매번 사용하는 bind를 생략하는 방법이 있을까요?

1. 화살표 함수 사용

class MyComponent extends React.Component {
  handleClick = () => {
    console.log("Button clicked: ", this.props.value);
  };

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

2. 함수형 컴포넌트와 Hooks 사용

import React, { useState } from "react";

function MyComponent({ value }) {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    console.log("Button clicked: ", value);
    setCount(count + 1);
  };

  return <button onClick={handleClick}>Click me {count} times</button>;
}

export default MyComponent;

 

🍲 JSX 내부에 이벤트 핸들러로 콜백 함수를 전달하는 것과 함수를 전달해서 사용하는 것은 어떤 차이가 있을까요?

1. 콜백 함수를 전달하는 경우

직접 인라인에서 화살표 함수나 익명 함수를 정의하면 해당 컴포넌트가 렌더링 될 때마다 새로운 함수 인스턴스가 생성된다.

이는 불필요한 메모리 할당과 가비지 컬렉션을 초래할 수 있다.

특히, 자주 렌더링 되는 컴포넌트에서 성능에 영향을 줄 수 있다.

 

2. 함수를 전달하는 경우

함수를 전달하는 방식은 함수 인스턴스를 재사용할 수 있다.

이 방법은 성능 최적화에 도움이 되며, 특히 불필요한 리렌더링을 줄일 수 있다.

 

 

🍲 왜 리스트의 key값으로 index를 사용하는 것은 안티 패턴일까요?

1. 비효율적인 업데이트

React는 리스트 변경 시 렌더링을 효율적으로 하기 위해 key 값을 사용하여 변경되지 않은 항목을 찾아낸다.

인덱스를 사용하면 변경되지 않은 항목의 인덱스도 바뀔 수 있어 오류가 날 수 있다.

 

2. 불필요한 리렌더링

리스트의 요소가 추가되거나 삭제되면, 인덱스를 키 값으로 사용했을 때 모든 항목이 변경된 것으로 인식된다. 

이로 인해 불필요한 렌더링이 발생하게 되고, 성능에 영향을 준다.

 

 

🍲 데이터에 고유한 id 값이 없다면 어떻게 key 값을 설정하는 게 좋을까요?

1. 겹치지 않는 속성 사용

항목에 겹치지 않는 속성이 있다면 이를 이용해 key 값을 설정할 수 있다.

 

2. 라이브러리 사용

uuid 등 고유한 ID를 생성해 주는 라이브러리를 사용해 각 항목의 key 값을 설정할 수 있다.

 

 

🍲 Ref를 사용해야 하는 케이스는 무엇이 있을까요?

1. DOM 요소에 접근 및 조작

포커스를 설정하거나 텍스트를 선택하는 등 DOM 요소에 직접 접근, 조작할 때 사용한다.

 

2. 하위 컴포넌트 메서드 호출

하위 컴포넌트의 메서드를 직접 호출해야 하는 경우 사용한다.

하위 컴포넌트의 요소의 크기를 계산하거나, 커스텀 포커스 함수 호출 등에 사용할 수 있다.

 

 

🍲 Ref를 남용하면 안 되는 이유는 무엇일까요?

1. 선언적 프로그래밍 문제

React는 선언적 프로그래밍 방식을 채택하고 있다.

이는 UI의 변화를 명시적으로 작성하는 대신, 상태와 속성을 기반으로 자동으로 UI를 업데이트하는 방식이다.

ref를 남용하면 이러한 선언적 프로그래밍 패러다임에 벗어나게 되어 가독성과 관리 측면에서 문제가 발생할 수 있다.

 

2. 가독성과 유지보수 어려움

ref는 DOM 접근이나 컴포넌트 인스턴스 조작을 직접 수행하기 때문에 코드가 복잡해지고 유지보수가 어려워진다.

 

3. 컴포넌트 간의 독립성 감소

ref를 통해 부모 컴포넌트에서 하위 컴포넌트의 메서드를 직접 호출하면, 컴포넌트 간의 독립성이 떨어진다.

 

댓글