도은
- React는 UI를
렌더링
하기 위한 자바스크립트 라이브러리이다. - UI는 버튼, 텍스트, 이미지와 같은 작은 요소로 구성
- React를 통해 이 작은 요소들을
재사용
가능하고중
첩할 수 있는 컴포넌트로조합
가능하다.
Your first component
- React는
컴포넌트
라고 불리는독립적인 UI 조각들
로 구성 - React 컴포넌트는 마크업을 포함할 수 있는 자바스크립트 함수이다.
컴포넌트: UI 구성 요소
- 웹에서는 HTML을 통해
<h1>
,<li>
와 같은 태그를 사용하여 문서를 만들 수 있다. - 마크업은 스타일을 위한 CSS, 상호작용을 위한 JS와 결합 → UI의 기반
⭐️ React를 사용하면, 마크업 & CSS, JS를 재사용 가능한 UI 요소인 컴포넌트로 결합 가능하다
- 프로젝트 규모가 커질수록, 이미 작성한 컴포넌트를 재사용 → 생산성 ⬆️
컴포넌트 정의하기
⭐️ React 컴포넌트는 마크업을 포함할 수 있는 자바스크립트 함수이다.
브라우저에 표시되는 내용
<section>
은 소문자 → React는 HTML 태그를 가리킨다고 해석<Profile />
은 대문자로 시작 → React는 컴포넌트를 사용한다고 해석
컴포넌트 중첩 및 구성
- 컴포넌트는 일반 자바스크립트 함수이므로 같은 파일에 여러 컴포넌트 포함 가능
Importing and exporting components
📖 DEEP DIVE ) Default와 Named Exports
- 자바스크립트에서는 default export와 named export 라는 2가지 방법으로 값을 export 하는 것이 가능
- 한 파일에는 하나의 default export만 존재할 수 있고, named export는 여러 개 존재 가능성
- 보편적으로는
- 한 파일에서 하나의 컴포넌트만 export할 때는 default export 방식
- 여러 컴포넌트를 export할 경우 named export를 사용
- 어떤 방식을 사용하든, 컴포넌트와 파일의 이름을 의미있게 명명하는 것이 중요
Writing markup with JSX
⭐️ JSX는 자바스크립트를 확장한 문법, 자바스크립트 파일에서 HTML과 비슷하게 마크업을 작성할 수 있도록 해준다.
JSX: JavaScript에 마크업 포함하기
- Web은 HTML, CSS, JavaScript를 기반으로 구성
- 보통은 HTML, CSS, JavaScript를 분리된 파일로 관리
- Web이 더욱 인터랙티브해지면서, 로직이 내용을 결정하는 경우가 많아졌다.
- 렌더링 로직과 마크업이 함께 있다면
- 매번 변화가 생길 때 마다 서로 동기화된 상태 유지
⭐️ React 컴포넌트는 React가 브라우저에 마크업을 렌더링할 수 있는 JavaScript 함수이다.
📖 DEEP DIVE ) 왜 여러 JSX 태그를 하나로 감싸줘야 할까?
- JSX는 HTML처럼 보이지만, 내부적으로 일반 JavaScript 객체로 변환
- 하나의 함수에서 객체 2개를 반환한다고 생각해보자, 이럴 떄 배열로 감싸야하지 않는가
- 이것처럼 하나의 태그 또는 Fragmented로 감싸지 않으면, 두 개의 JSX 태그를 반환할 수 없다.
JavaScript in JSX with curly braces
중괄호 사용하기
- 중괄호
{ }
사이에 JavaScript를 사용할 수 있다.
이중 중괄호 사용하기
- JSX는 문자열, 숫자 및 JS 뿐만 아니라 객체 전달 가능
- JSX에 객체를 전달하려면
person={{ name: 'Hedy Lamarr' }}
와 같이 가능
Conditional rendering
- 컴포넌트는 조건에 따라 다른 항목을 표시해야 하는 경우가 많다.
- React는
if
문,&&
및? :
연산자와 같은 자바스크립트 문법을 사용하여 조건부로 JSX를 렌더링할 수 있다.
조건부로 null을 사용하여 아무것도 반환하지 않기
- 어떤 경우에는 조건에 따라 아무것도 렌더링하고 싶지 않을 수 있는데
- 이럴 때 null을 반환
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
🤔 간혹 아무것도 렌더링하고 싶지 않을 때 <></>을 리턴하기도 하는데, 다른걸까?
- 공식문서 Fragment는 DOM에 별도의 노드를 추가힞 않고 여러 자식을 그룹화할 수 있다고 명시되어 있다.
- 위와 같은 용도로 사용하고
- 반환할 JSX가 없는 것의 의도한다면 null을 사용하는 것이 좋을 것 같다.
Keeping components pure
Purity
- 순수 함수는 다음과 같은 특징을 가지고 있는 함수이다.
- 같은 입력이 주어졌다면, 순수함수는 같은 결과를 반환
- React는 순수 함수 컨셉을 기반으로 설계
- React는 작성되는 모든 컴포넌트가 순수 함수일 것이라 가정
- 즉, 같은 입력이 주어진다면 반드시 같은 JSX를 반환한다는 것을 의미
Side Effect
- React의 렌더링 과정은 항상 순서해야 한다.
- 컴포넌트는 렌더링하기 전에 존재했던 객체나 변수들을 변경하지 말고, JSX만 반환
📖 DEEP DIVE ) 엄격 모드에서 순수하지 않은 연산을 감지
- React는 개발 중에 각 컴포넌트의 함수를 두 번 호출하는 "엄격 모드"를 제공
- 컴포넌트 함수를 두 번 호출함으로써, 엄격 모드는 이러한 규칙을 위반하는 컴포넌트를 찾는데 도움
- 순수함수 컴포넌트라면, 두 번 호출해도 아무 것도 변경되지 않는다.
부작용을 일으킬 수 있는 지점
- 함수형 프로그래밍은 순수성에 크게 의존하지만
- 언젠가는, 어딘가에서, 무언가가 바뀌어야 한다.
- 이러한 변화들(화면 업데이트, 애니메이션 시작, 데이터 변경)을 사이드 이펙트라고 한다.
- 렌더 중에 발생하는 것이 아니라, 사이드에서 발생하는 현상
⭐️ React에서는 사이드 이펙트는 보통 이벤트 핸들러에 포함된다.
- 이벤트 핸들러가 컴포넌트 내부에 정의되어 있다고 하더라도
- 렌더링 중에 실행 X → 이벤트 핸들러는 순수할 필요 X
Your UI as a tree
- React는 서로 중첩된 많은 컴포넌트로 구성
- React는 어떻게 컴포넌트 구조를 추적하는 것일까?
트리로서의 UI
- 브라우저는 DOM과 CSSOM을 모델링 하기 위해 트리 구조를 사용
렌더트리
- 컴포넌트를 중첩하면, 부모 컴포넌트와 자식 컴포넌트의 개념 → 각 부모 컴포넌트는 다른 컴포넌트의 자식이 될 수 있다.
📖 DEEP DIVE ) 렌더 트리에서 HTML 태그는 어디에?
- 렌더 트리는 React 컴포넌트로만 구성되어 있다.
- React는 모바일이나 데스크톱 플랫폼에서 렌더링될 수 있으며, 다른 UI 기본 요소를 사용할 수도 있는 것
- React 렌더 트리는 렌더링되는 플랫폼에 관계 없이 제공되는 것
모듈 의존성 트리
- 컴포넌트를 분리하고, 로직을 별도의 파일로 분리하면 → JS 모듈
- 모듈 의존성 트리의 각 노드는 모듈
- 의존성 트리는 React 앱을 실행하는 데 필요한 모듈을 결정
- React 앱을 프로덕션용으로 빌드할 때, 클라이언트에 제공할 모든 JS를 번들로 묶는 빌드 단계 존재하는데
- 이 작업을 수행하는 번들러, 번들러는 의존성 트리를 사용하여 포함해야 할 모듈을 결정
🤔 모듈 의존성 트리는 누가 생성하는 것?
- 번들러
- 번들러는 엔트리 포인트에서 시작해 필요한 모듈을 모두 탐색
- 트리 형태로 의존성 관계를 분석
🤔 의존성 트리는 빌드 시에만 생성?
- 개발 서버 실행 시에도 생성
- 개발 중에는 파일이 변경될 때마다 이 트리를 다시 생성하거나 갱신(HMR, Hot Module Replacement)
- vite의 경우
- 파일 시스템 감지 라이브러리(chokidar)를 사용해, 파일의 변경을 실시간으로 감지
- 파일이 변경되면, 모듈을 찾아내서 핫 리로드 메시지를 브라우저로 전송
- 브라우저는
WebSocket
을 통해 수신 - 파일이 수정되면, 서버가 WebSocket을 통해 브라우저에 해당 모듈을 교체하라고
- 브라우저는 WebSocket을 통해 받은 정보를 바탕으로, 변경된 모듈만 교체 & 나머지 페이지는 그대로 유지