내일배움캠프 React_7기 TIL - 17. React 강의 2주차 정리

·2024년 10월 29일
1

컴포넌트

UI를 재사용이 가능한 개별적인 여러 조각으로 나누는것
1.함수형 컴포넌트
2.클래스형 컴포넌트
react에서는 함수형 컴포넌트 사용을 권장한다.
컴포넌트는 jsx를 return하는 함수이다.

컴포넌트를 만들 때 반드시 가장 첫 글자는 대문자

폴더는 소문자로 시작하는 카멜케이스, 컴포넌트 파일은 대문자로 시작하는 카멜 케이스


JSX

  • Javascript를 확장한 문법, JS의 모든 기능이 포함되어 있으며 React Element를 생성하기 위한 문법이다. HTML을 품은 JS === JSX

JSX에서 쓰는 <div> ~~</div> 요소는 DOM요소인가?
정확히는 React요소이다. 가상돔(Virtual DOM)

브라우저는 jsx파일을 직접 해석할 수 없기에 babel을 이용하여 jsx를 js로 변환한다.

변환 전

const Element = <div className="greeting">hello</div>

변환 후

const Element = React.createElement(
  'div',
  {className:'greeting}, 
  'hello'
   );
  • JSX식에는 하나의 태그만 있어야 한다.

props

부모 컴포넌트가 자식 컴포넌트에게 물려준 데이터, 컴포넌트 간의 정보 교류 방법
props는 반드시 위에서 아래로 흐른다. (부모 → 자식)
props는 읽기 전용으로 취급하며 변경하지 않는다. (즉, 컴포넌트 내부에서 직접 변경하지 않아야 한다. 단방향 데이터 흐름 원칙에 따른 것이다.)
props는 객체 리터럴(object literal) 형태로, 키-값 쌍으로 구성된다.

// 부모 컴포넌트
function ParentComponent() {
return <ChildComponent name="홍길동" age={25} />;
}

부모 컴포넌트에서 자식 컴포넌트에 name과 age라는 속성을 전달한다고 하면, 전달된 props는 아래와 같은 형식의 객체 리터럴이다.

  {
  name: "홍길동",
  age: 25
}

이 때 접근은 {props.name}, {props.age}로 가능하지만, 구조분해할당을 사용하여 props를 쉽게 가져올 수 있다.

function ChildComponent({ name, age }) {
return (
  <div>
    이름: {name}, 나이: {age}
  </div>
);
}

props Children

자식 컴포넌트로 정보를 전달하는 또다른 방법 (props의 일부)
ParentComponent에서 <ChildComponent>로 전달한 <p> 태그가 {props.children}으로 전달되면, <ChildComponent>내부에서 {props.children}으로 접근하여 내용을 출력할 수 있다.

function ParentComponent() {
return (
  <ChildComponent>
    <p>이 내용이 props.children으로 전달됩니다.</p>
  </ChildComponent>
);
}

function ChildComponent(props) {
return (
  <div>
    <h2>Child Component</h2>
    {props.children} {/* 자식 콘텐츠 렌더링 */}
  </div>
);
}

즉, 부모 컴포넌트에서 자식 컴포넌트의 태그 사이에 넣은 내용은 자동으로 props.children으로 전달된다.

props.children을 활용하면 컴포넌트의 내용(콘텐츠)을 동적으로 구성할 수 있어, 더 유연하고 재사용성이 높은 컴포넌트를 만들 수 있다고 한다. Layout 컴포넌트를 만들 때도 유용하게 사용한다.


state

컴포넌트 내부에서 바뀔 수 있는 값
UI에 즉각적인 데이터 반영을 위해 사용한다.
State를 만들 때는 useState()를 사용한다.

useState Hook

const [ value, setValue ] = useState(initial state); 

state 사용 예시

import { useState } from "react";

function App() {
const [text, setText] = useState("");
const handleInputChange = (e) => {
  setText(e.target.value);
};
return (
  <>
    <input type="text" onChange={handleInputChange} />
    {text}
  </>
);
}

export default App;

input 필드에서 onChange 이벤트를 통해 상태(state)가 변경되고, 그 상태를 출력하여 UI가 상태에 따라 바뀌게 된다.

불변성

불변성이란 메모리에 있는 값을 변경할 수 없는 것을 말한다.

  • 불변성을 깨뜨리는 것의 문제
    불변성을 유지하지 못하는 변경 가능한 방법은 원래의 데이터 구조를 직접 변경한다는 뜻이다.

    변경 가능한 방법(Mutable way)으로 코드를 짜게 되면, 프로그램의 다른 부분이 해당 데이터 구조를 참고하고 있을 때, 예상치 못한 변경으로 인한 버그 발생의 위험성이 있다.
    또한 원본 데이터가 여러 곳에서 변경이 될 수 있다면 이러한 버그는 추적이 어려워진다.

    따라서 불변성을 유지하는 방법(Immutable way)을 사용하는 것이 좋다.

리액트에서 불변성이 가지는 의의

리액트에서는 화면을 리렌더링할지 말지 결정할 때 상태(state)의 변화를 확인 (얕은 비교). 상태가 변경되었을 때, 리렌더링한다.

이 때, 상태가 변경 여부를 확인하는 방법은 상태의 변화 전후의 주소값을 비교하는 것이다. 원시 데이터의 경우 값이 변경되면 새로운 메모리 주소가 할당되므로 리액트가 이를 쉽게 감지할 수 있다. 그러나 원시 데이터가 아닌 복합 데이터(객체, 배열 등)의 값을 직접 수정할 경우 메모리 주소가 변경되지 않기 때문에 리액트는 상태의 변화를 인지하지 못할 수 있다.

결론
따라서, 리액트에서는 불변성을 유지하는 방법(Immutable way)을 사용하는 것이 좋다. 이를 통해 상태를 변경할 때는 항상 새로운 객체나 배열을 생성하고, setState를 사용하여 상태를 업데이트 해야 한다.

얕은 비교(shallow comparison): 상태의 변화를 감지할 때 리액트가 사용하는 비교 방식. 이 방법은 객체의 첫 번째 레벨의 프로퍼티만 비교합니다.


렌더링

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

  • triggering UI를 주문하고 주방으로 전달하는것
    1. 첫 리액트 앱을 실행했을 때
    2. 현재 리액트 내부에 상태 변경이 발생했을 때
    • 컴포넌트 내부 state 변경
    • 컴포넌트에 새로운 props가 들어올 때
    • 상위 컴포넌트에서 두 이유로 렌더링이 발생했을 때
  • rendering 주방에서 컴포넌트가 UI를 만들고 준비하는 것
  • commit 리액트가 준비된 UI를 손님 테이블에 올려놓는 것

리렌더링

컴포넌트 상태에 변화가 생기면 리렌더링 발생
이때 여러 상태가 변경됐다면 리액트는 이를 자료구조에 넣어 순서 관리

리렌더링 !== 브라우저 렌더링

DOM과 Virtual DOM

DOM

웹페이지를 이루는 컴포넌트를 element라고 하는데, DOM은 이 elements들이 트리 형태로 표현한 것(=DOM TREE)
트리의 요소 하나하나를 노드 라고 부른다.
각각의 ‘노드’는 해당 노드에 접근과 제어(DOM 조작)를 할 수 있는 API를 제공한다.

// id가 demo인 녀석을 찾아, 'Hello World!'를 대입해줘.
document.getElementById("demo").innerHTML = "Hello World!";

document.~~ 가 DOM API이다.

Virtual DOM

리액트는 가상DOM을 이용하여 실제DOM을 변경하는 작업을 효율적으로 수행한다.

DOM조작 과정


리액트는 2가지 버전의 가상DOM을 가지고 있다.
1. 화면이 갱신되기 전 구조가 담긴 가상DOM
2. 화면 갱신 후 보여야 할 가상DOM

diffing (비교)
state가 변경되면 1번과 2번을 비교해여 어느 element에 변화가 일어났는지 빠르게 파악

reconciliation (재조정)
파악이 끝나면 변경이 일어난 그 부분만 실제DOM에 적용시켜준다. 이때, 한건씩 적용시키는 것이 아니라 변경사항을 모두 모아 한번만 적용시킨다(=Batch Update🔥)

Batch Update :
여러 개의 업데이트 작업을 한 번에 묶어 일괄적으로 처리하는 것을 의미(=일괄 업데이트)

브라우저 렌더링(페인팅)

리액트가 실제DOM을 업데이트하면, 브라우저의 렌더링 엔진에 의해 변경사항이 화면에 반영된다.

브라우저 렌더링 과정
1. 스타일 계산 : HTML과 CSS를 분석하여 각 요소의 스타일 계산
2. 레이아웃 : 각 요소의 위치와 크기 계산
3. 페인팅 : 레이아웃 단계에서 계산된 정보를 바탕으로 요소를 화면에 그린다.

브라우저의 렌더링과 리액트의 렌더링은 엄연히 다른 독립적인 프로세스이다.

profile
내배캠 React_7기 이수중

0개의 댓글

관련 채용 정보