brunch

You can make anything
by writing

C.S.Lewis

by florent Jul 09. 2024

React.js

florent의 개발 적응기




이 글의 주요 내용

[선언적 프로그래밍 vs 명령적 프로그래밍 (Declarative vs Imperative Programming)]

[React.js]

[JSX(JavaScript XML)]

[React.js 스타일링(styling)]

[React.js 컴포넌트(Component)]

[조건부 렌더링]

[훅(Hook)]

[useState]

[구조 분해 할당 (Destructuring Assignment)]

[React.js 이벤트 핸들링]

[전개 연산자 (Spread Operator)]

[컴포넌트 트리 관리]





[선언적 프로그래밍 vs 명령적 프로그래밍 (Declarative vs Imperative Programming)]

React는 선언적 프로그래밍 방식을 채택 ⇒ "무엇"을 할지 설명하는 방식으로, 명령적 프로그래밍이 "어떻게" 할지를 설명하는 것과 대조


(1) 명령적 프로그래밍 (Imperative Programming): "어떻게" 할 지를 단계별로 지시하는 것으로, 프로그램의 상태를 변경하는 명령문들의 순서를 나열

DOM을 직접 조작

각 단계를 명시적으로 프로그래머가 지정

상태 변경의 과정을 직접 관리


(2) 선언적 프로그래밍 (Declarative Programming): "무엇"을 원하는지 설명하는 것으로, 원하는 결과를 묘사하고, 시스템이 그 결과를 얻는 방법을 결정하게 함

상태에 따라 UI가 어떻게 보여야 할지 설명

React가 실제 DOM 업데이트를 처리

컴포넌트는 주어진 props에 따라 어떻게 렌더링될지만 정의



[React.js]


[리액트(React.js)란?]

React.js는 사용자 인터페이스(User Interface, UI)를 구축하기 위한 자바스크립트 라이브러리로, 프론트엔드 프레임워크로 여겨지기도 함

Facebook(현 Meta)에서 개발했으며, 컴포넌트 기반 아키텍처를 사용하여 재사용 가능하고 모듈화된 UI 요소를 만들 수 있음


[React.js의 주요 특징]

컴포넌트 기반 아키텍처 (Component-based Architecture)

가상 DOM (Virtual DOM)

JSX (JavaScript XML)

단방향 데이터 흐름 (One-way Data Flow)

선언적 프로그래밍 (Declarative Programming)


[컴포넌트 (Components)]

컴포넌트란, UI를 구성하는 독립적이고 재사용 가능한 조각을 의미

각 컴포넌트는 자체적인 로직, 구조, 스타일을 가질 수 있음


[JSX (JavaScript XML)]

JSX는 JavaScript 내에서 HTML과 유사한 구문을 사용할 수 있게 해주는 React의 문법 확장



[가상 DOM (Virtual DOM)]

가상 DOM은 실제 DOM의 가벼운 복사본으로, React는 가상 DOM을 사용하여 실제 DOM 업데이트를 최적화


[상태 관리 (State Management)]

React 컴포넌트는 자체 상태를 가질 수 있으며, 이를 통해 동적인 UI를 구현 가능


[프로퍼티 (Props)]

Props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방법


[생명주기 메서드 (Lifecycle Methods)]

클래스 컴포넌트에서는 생명주기 메서드를 통해 컴포넌트의 다양한 단계에서 코드를 실행 가능

함수형 컴포넌트에서는 useEffect 훅을 사용하여 비슷한 기능을 구현


[Diffing (차이점 비교)]

React는 효율적인 UI 업데이트를 위해 가상 DOM을 사용하여 변경 사항을 비교하고 실제 DOM에 최소한의 변경만을 적용 ⇒ 이 과정을 "재조정(Reconciliation)"이라고도 함

이러한 특징들을 통해 React는 효율적이고 유지보수가 쉬운 웹 애플리케이션을 구축 가능

컴포넌트 기반 구조는 코드의 재사용성을 높이고, 가상 DOM과 효율적인 렌더링 메커니즘은 애플리케이션의 성능을 향상



[JSX(JavaScript XML)]


[JSX란?]

JSX는 JavaScript XML의 약자로, JavaScript 내에서 HTML과 유사한 구문을 사용하여 React 컴포넌트를 작성할 수 있게 해주는 문법

JSX는 React 요소를 생성하기 위해 사용되며, JavaScript 코드와 HTML 코드를 결합할 수 있게 해줌

JSX를 사용하는 이유는 UI를 더 직관적이고 읽기 쉽게 작성할 수 있기 때문



[JSX 문법]


(1) HTML 태그 사용: JavaScript 코드 안에 HTML 태그를 직접 작성 가능


(2) JavaScript 표현식 사용: JSX 내부에서는 중괄호 {}를 사용하여 JavaScript 표현식을 사용


(3) JSX 안에서의 스타일링: JSX에서 스타일을 적용할 때는 객체를 사용하여 인라인 스타일을 정의


(4) 클래스 속성: HTML의 class 속성은 JSX에서 className으로 작성해야함 ⇒ JavaScript의 class 예약어와의 충돌을 피하기 위함


(5) 조건부 렌더링: JSX에서 조건부 렌더링을 할 때는 JavaScript의 삼항 연산자를 사용 가능


(6) JSX에서 리스트를 렌더링할 때는 map() 함수를 사용하고 각 요소에 고유한 key를 지정


(7) 컴포넌트 혼합 사용: JSX에서는 다른 컴포넌트를 포함하여 재사용 가능한 UI 요소를 만들 수 있음


(8) 이벤트 핸들링: JSX에서 이벤트를 처리할 때는 JavaScript 함수와 이벤트 핸들러를 사용


이벤트 유형 및 JSX 속성


(9) JSX 내부에서 주석을 작성할 때는 중괄호와 슬래시를 사용



[React.js 스타일링(styling)]


[이미지 사용]

React에서 이미지를 사용할 때는 항상 닫는 태그를 사용해야 하며, src 속성에 동적 값을 할당 가능


[인라인 스타일링]

React에서 인라인 스타일은 객체로 전달되며, 속성명은 camelCase를 사용


[CSS 모듈 사용]

React에서는 CSS 모듈을 사용하여 스타일의 범위를 컴포넌트로 제한할 수 있음


[조건부 스타일링]

React에서는 조건에 따라 동적으로 스타일을 적용할 수 있음



[React.js 컴포넌트(Component)]


[컴포넌트란]

React 컴포넌트는 UI의 재사용 가능한 부분을 나타냄

일반적으로 컴포넌트 이름은 파스칼 케이스(PascalCase)로 작성

함수형 컴포넌트와 클래스형 컴포넌트 두 가지 방식으로 생성


(1) 함수형 컴포넌트

함수형 컴포넌트는 JavaScript 함수로 정의되며, props를 인자로 받아 JSX를 반환

간단하고 읽기 쉬운 구조를 가짐

React 16.8 이후로 Hooks를 사용하여 상태와 생명주기 기능을 사용할 수 있음

성능상 이점이 있으며, 최근 React 개발에서 권장되는 방식


(2) 클래스형 컴포넌트

클래스형 컴포넌트는 React.Component를 상속받아 정의되며, render() 메서드를 통해 JSX를 반환

this 키워드를 사용하여 props와 state에 접근

생명주기 메서드(예: componentDidMount, componentDidUpdate)를 사용할 수 있음

복잡한 UI 로직을 구현할 때 유용할 수 있음



[컴포넌트의 Import와 Export]

컴포넌트는 모듈 시스템을 사용하여 컴포넌트를 내보내고 불러올 수 있음

내보내기 (Export)

불러오기 (Import)



[Props(속성)]

Props는 주로 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 데 사용 ⇒ Props는 부모 컴포넌트에서 자식 컴포넌트로 전달되는 데이터

Props는 읽기 전용이므로 자식 컴포넌트는 props를 직접 수정할 수 없음

function으로 임의의 파라미터를 설정하여 props 함수를 정의한 후, 해당 속성을 사용할 곳에서 태그 형태로 props 함수 사용

Props를 활용하여 컴포넌트간 데이터 전달 예시



[데이터 매핑 (Data Mapping)]

배열 데이터를 컴포넌트로 변환할 때 map 함수를 사용



[조건부 렌더링]


[조건부 렌더링 (Conditional Rendering)]

조건부 렌더링은 특정 조건에 따라 다른 컴포넌트나 요소를 렌더링하는 기법


(1) 삼항 연산자 (Ternary Operator) 활용


(2) React.js의 && 연산자 활용

falsy 값 (0, empty string 등)을 사용할 때 주의해야 함 (의도치 않게 렌더링 실패가 될 수 있음)




[훅(Hook)]


[훅 (Hooks)]

훅은 React 16.8에서 도입된 기능으로, 함수형 컴포넌트에서 상태(state)와 생명주기(lifecycle) 기능을 사용할 수 있게 해줌

클래스 컴포넌트 없이 상태 관리 가능

로직의 재사용성 향상

복잡한 컴포넌트를 쉽게 이해하고 관리 가능


[주요 훅]

useState: 상태 관리

useEffect: 부수 효과 처리

useContext: 컨텍스트 사용

useReducer: 복잡한 상태 로직 처리

useCallback, useMemo: 성능 최적화

useRef: DOM 요소 참조 또는 변경 가능한 값 저장


[상태 관리 (State Management)]

상태 관리는 React 애플리케이션에서 동적 데이터를 다루는 핵심 개념으로, 함수형 컴포넌트에서는 useState 훅을 사용하여 상태를 관리

컴포넌트별 로컬 상태 관리

상태 변경 시 자동으로 리렌더링 트리거

불변성(Immutability) 유지 중요



[생명주기 메서드 (Lifecycle Methods)]

생명주기 메서드는 컴포넌트의 다양한 단계(마운트, 업데이트, 언마운트)에서 실행되는 특별한 메서드로, 함수형 컴포넌트에서는 useEffect 훅을 사용하여 유사한 기능을 구현




[useState]


[useState란?]

useState는 React의 Hook 중 하나로, 함수형 컴포넌트에서 상태(state)를 관리할 수 있게 해줌


[useState의 특징]

상태 초기화: 초기 상태 값을 설정할 수 있습니다.

상태 읽기: 현재 상태 값을 읽을 수 있습니다.

상태 업데이트: 상태를 변경할 수 있는 함수를 제공합니다.


[useState의 구조]

컴포넌트가 처음 렌더링될 때 useState가 호출되며, 초기 상태가 설정

이후 렌더링에서는 최신 상태 값을 반환

setState 함수를 호출하면 상태가 업데이트되고 컴포넌트가 다시 렌더링됨

사용 예시


[제어된 컴포넌트(Controlled Component)]

제어된 컴포넌트는 React에서 폼 요소의 상태를 관리하는 방식으로, HTML에서 <input>, <textarea>, <select> 등의 폼 요소는 자체적으로 상태를 관리하지만, React에서는 이러한 상태를 컴포넌트의 state로 관리

단일 진실의 원천(Single Source of Truth): 컴포넌트의 state가 폼 데이터의 유일한 출처가 됨

즉각적인 유효성 검사: 사용자 입력에 대해 즉시 반응하고 유효성을 검사

조건부 렌더링: 입력값에 따라 UI를 동적으로 변경

다중 입력 처리: 여러 입력 필드를 가진 폼의 경우, 각 필드에 대해 별도의 핸들러를 만드는 대신 하나의 핸들러로 여러 입력을 관리 가능


[제어된 컴포넌트의 이점]

데이터 일관성: React state와 폼 입력값이 항상 동기화

즉각적인 필드 유효성 검사: 사용자가 입력하는 대로 유효성을 검사할 수 있음

조건부 렌더링: 특정 입력값에 따라 다른 UI 요소를 보여줄 수 있음

폼 데이터 조작: 제출 전에 입력된 데이터를 쉽게 수정하거나 포매팅


[구조 분해 할당 (Destructuring Assignment)]

구조 분해 할당은 ES6에서 도입된 JavaScript 문법으로, 배열이나 객체의 속성을 쉽게 추출하여 별도의 변수에 할당할 수 있게 해줌

객체와 배열 모두에 적용 가능하며, 중첩된 객체나 배열에도 사용 가능

기본값 설정 가능, 변수 이름 변경 가능 (객체 구조 분해에서)

나머지 요소 할당 가능 (Rest 패턴)

일반적인 변수 할당(’변수 = 객체’)과는 반대 순서로 작성해야 함: ‘부분 객체 = 변수’



[React.js 이벤트 핸들링]


React.js에서의 이벤트 핸들링 방식

(1) 이벤트 핸들러 정의: 함수형 컴포넌트 내부에 이벤트 처리 함수를 정의

(2) 이벤트 리스너 연결: JSX에서 해당 요소에 이벤트 리스너를 연결

(3) 이벤트 객체 처리: 필요한 경우 이벤트 객체를 활용

즉각적인 필드 유효성 검사: 사용자가 입력하는 대로 유효성을 검사

조건부 렌더링: 특정 입력값에 따라 다른 UI 요소를 보여줄 수 있음

폼 데이터 조작: 제출 전에 입력된 데이터를 쉽게 수정하거나 포매팅



[전개 연산자 (Spread Operator)]

전개 연산자(...)는 ES6에서 도입된 기능으로, 배열이나 객체의 요소를 펼치는 데 사용 ⇒ React에서 상태를 업데이트할 때 매우 유용


(1) 배열에 사용된 전개 연산자


(2) 객체에 사용된 전개 연산자


(3) React.js 내 전개 연산자 사용 예시



[컴포넌트 트리 관리]


[컴포넌트 트리 관리 (Component Tree Management)]

React 애플리케이션은 일반적으로 여러 컴포넌트로 구성되며, 이들은 트리 구조를 형성

상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달하고, 하위 컴포넌트에서 상위 컴포넌트의 상태를 변경하는 방법을 이해하는 것이 중요


[컴포넌트 트리의 주요 개념]

Props (속성): 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방법

Lifting State Up (상태 끌어올리기): 여러 컴포넌트가 공유하는 상태를 공통 조상 컴포넌트로 이동시키는 기법

Callback 함수: 자식 컴포넌트에서 부모 컴포넌트의 상태를 변경할 수 있게 하는 방법


[컴포넌트 트리 관리의 이점]

데이터 흐름이 명확해집니다 (항상 위에서 아래로)

상태 관리가 중앙화되어 유지보수가 쉬워짐

컴포넌트 간 결합도가 낮아져 재사용성이 높아짐


[컴포넌트 트리 구성시 주의할 점]

컴포넌트 트리가 깊어질수록 props를 전달하는 과정이 복잡해질 수 있음 ⇒ 이런 경우 Context API나 상태 관리 라이브러리(예: Redux)를 고려할 수 있음

각 컴포넌트의 책임을 명확히 하고, 가능한 작고 집중된 컴포넌트를 만들어야 함


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari