React 처음 배우기 (1)

ndy·2023년 11월 21일

React

목록 보기
1/2

https://www.inflearn.com/course/%EC%B2%98%EC%9D%8C-%EB%A7%8C%EB%82%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8
강의를 참고했습니다.


SPA(Single Page Application)

웹 애플리케이션 또는 웹사이트가 하나의 페이지로 구성되어 있으며,
사용자와의 상호작용에 따라 필요한 부분만 동적으로 업데이트되는 형태를 말합니다.

주요 특징

  • 페이지 로딩 시간 감소: 초기에 웹 애플리케이션의 필수 리소스를 한 번에 불러오고, 이후 데이터만 변경하여 화면을 업데이트하기 때문에 로딩 시간이 감소합니다.

  • 사용자 경험 개선: 페이지 전환 없이 애플리케이션이 동작하기 때문에 데스크탑 애플리케이션과 유사한 사용자 경험을 제공할 수 있습니다.

  • front-end와 back-end의 분리: back-end는 API를 통해 데이터를 제공하는 역할에 집중하고, front-end는 이 데이터를 활용하여 UI를 구성합니다.


JavaScript?

스크립트 언어의 한 종류입니다.

스크립트 언어?

  • 스크립트 언어는 컴파일을 거치지 않고, 스크립트를 해석(interpret)하는 방식으로 실행됩니다.
  • 예로는 JavaScript, Python, Ruby, PHP등이 있으며, 이들은 웹 페이지의 동적인 동작을 구현하거나, 서버 사이드 스크립팅, DB관리 등 다양한 분야에 활용됩니다.
  • 하지만 컴파일 언어에 비해 실행 속도가 느릴 수 있습니다.

객체지향 언어와 스크립트 언어의 차이?

  • 스크립트 언어는 간단한 작업을 빠르게 처리하는데 중점을 둔다면,
    객체지향 언어는 시스템의 구조를 체계적으로 설계하는 데 중점을 둡니다.

  • 하지만 하나의 프로그래밍 언어가 스크립트 언어와 객체지향 언어의 특성을 동시에 가질 수 있습니다. (Python)


JavaScript의 문법

자료형

  • JavaScript에서는 변수를 선언할 때가 아닌 변수에 데이터가 대입되는 시점에 해당 변수의 자료형이 결정됩니다.
  • 이를 다이나믹 타이핑(동적 타이핑)이라고 부릅니다.

객체

  • JavaScript에서의 객체는 다른 객체지향 프로그래밍 언어의 객체와는 의미가 조금다릅니다.
  • key와 value로 이루어진 쌍의 집합을 의미합니다.

변수

var, let, const 이들 각각의 키워드는 변수의 스코프(유효 범위), 호이스팅(선언 위치), 재할당 가능 여부와 같은 특성을 가지고 있어, 사용 상황에 따라 적절하게 선택하여 사용해야 합니다.

  • var : 전통적인 변수 선언 키워드

    • 스코프: var로 선언된 변수는 함수 스코프를 가집니다. 즉, 함수 내에서 선언된 var 변수는 함수 내 전체에서 유효하며, 함수 외부에서 선언된 var 변수는 전역 스코프를 가집니다.

    • 호이스팅: var로 선언된 변수는 호이스팅되어 선언부가 함수의 최상단으로 끌어올려지는 것처럼 동작합니다. 단, 초기화는 실제 코드에 도달했을 때 이루어집니다.

    • 재할당: 재할당이 가능합니다.

  • let : ES6부터 추가된 키워드

    • 스코프: let으로 선언된 변수는 블록 스코프를 가집니다. 즉, 선언된 블록({}) 내부에서만 유효합니다.

    • 호이스팅: let으로 선언된 변수도 호이스팅되지만, var와 달리 "일시적 사각지대(Temporal Dead Zone, TDZ)"에 빠져서 선언 이전에 접근하려 하면 참조 에러(ReferenceError)가 발생합니다.

      console.log(myVar);   // undefined
      console.log(myLet); // ReferenceError: myLetVar is not defined
      
      var myVar = 'var로 선언된 변수';
      let myLet = 'let으로 선언된 변수';
    • 재할당: 재할당이 가능합니다.

  • const : ES6부터 추가된 키워드, 불변의 상수를 선언할 때 사용합니다.

    • 스코프: const로 선언된 상수도 블록 스코프를 가집니다.

    • 호이스팅: const 또한 호이스팅은 되지만 TDZ에 의해 선언 전에는 접근할 수 없습니다.

    • 재할당: const로 선언된 상수는 재할당이 불가능합니다. 선언 시 반드시 초기화해야 하며, 한 번 할당된 값은 변경할 수 없습니다.


함수 스코프와 블록 스코프가 뭐야?

  • 함수 스코프
function myFunction() {
  var functionScoped = '저는 함수 스코프입니다';
  if (true) {
    var stillFunctionScoped = '저도 함수 스코프입니다';
  }
  console.log(functionScoped); // 출력: 저는 함수 스코프입니다
  console.log(stillFunctionScoped); // 출력: 저도 함수 스코프입니다
}
myFunction();
console.log(functionScoped); // ReferenceError: functionScoped is not defined
  • 블록 스코프
function myFunction() {
  if (true) {
    let blockScoped = '저는 블록 스코프입니다';
    const anotherBlockScoped = '저도 블록 스코프입니다';
  }
  console.log(blockScoped); // ReferenceError: blockScoped is not defined
  console.log(anotherBlockScoped); // ReferenceError: anotherBlockScoped is not defined
}
myFunction();

호이스팅이 뭐야?

호이스팅은 자바스크립트에서 변수 및 함수 선언을 코드의 맨 위로 끌어올리는 것처럼 동작하는 특성을 말합니다.
var, let, const로 선언된 변수들은 각기 다른 방식으로 호이스팅이 적용됩니다.


연산자

일치 연산자

let a = 1;
let b = '1';

console.log(a == b); 	// true
console.log(a === b);	// false, 자료형이 같아야합니다.

함수

// function statement를 사용
// 함수 선언문은 호이스팅되어 코드의 상단으로 끌어올려집니다.
function sum(a, b) {
	return a + b;
}

// arrow function expresstion
// 화살표 함수 표현식은 변수에 할당되는 값이므로 호이스팅되지 않습니다.
const multiply = (a, b) => {
	return a * b;
}

React는 무엇인가?

UI를 만들기 위한 JavaScript 라이브러리입니다.

라이브러리?

특정 프로그래밍 언어에서 자주 사용되는 특정 기능을 수행하는 함수나 도구들의 모음입니다.
개발자는 필요한 기능을 가진 라이브러리를 선택하여 자신의 프로젝트에 가져다 사용할 수 있습니다.

프레임워크와 라이브러리의 차이

  • 프레임워크

    • 프레임워크는 라이브러리보다 더 포괄적인 개념으로, 애플리케이션의 기본 구조와 제공해야 할 기능의 템플릿을 제공합니다.
    • 프레임워크를 사용할 때는 프레임워크가 정의한 규칙과 방식을 따라야 합니다. 즉, 프레임워크가 애플리케이션의 흐름을 주도하며, 개발자는 프레임워크가 정의한 방식에 맞추어 코드를 작성합니다.
  • 라이브러리

    • 라이브러리는 개발자가 전체적인 흐름과 응용 프로그램의 구조를 제어하면서 필요한 부분에서 해당 기능을 호출하여 사용합니다.

React의 장점

빠른 업데이트와 렌더링 속도

렌더링(Rendering)이란

  • UI를 화면에 표시하는 과정을 말합니다.
  • React에서 렌더링은 가상 DOM을 이용하여 실제 DOM과의 차이를 계산하고, 이를 실제 DOM에 반영하는 과정을 포함합니다.

  • 렌더링 과정

    1. 초기 렌더링: 컴포넌트가 처음 화면에 나타날 때 발생, 컴포넌트render 메소드가 호출되어 JSX 코드가상 DOM 요소로 변환 후, 이를 실제 DOM에 삽입하여 사용자가 볼 수 있는 UI를 만듭니다.

    2. state 또는 props 변경: 컴포넌트state 또는 props가 변경되면 컴포넌트를 "재렌더링"합니다. 이는 새로운 가상 DOM을 생성하고 이전 가상 DOM과 비교하는 과정을 포함합니다.

    3. 가상 DOM의 비교: React는 이전 가상 DOM새로운 가상 DOM을 비교하여 실제로 변경된 부분만을 찾아냅니다. 이 과정을 "Diffing"이라고 하며, 성능 최적화를 위해 중요한 단계입니다.

    4. 실제 DOM의 업데이트: 변경된 부분만을 실제 DOM에 반영합니다. 최소한의 변경으로 UI를 최신 상태로 유지할 수 있습니다.

    5. side effect 발생: 렌더링이 완료된 후에는 useEffect와 같은 Hock을 통해 정의된 side effect가 실행됩니다.

Virtual DOM

Virtual DOM은 웹페이지와 실제 DOM 사이에 중간 매개체 역할을 하고 있습니다.

작동원리

  1. 변경 감지: 사용자 인터랙션 또는 데이터 변경으로 인해 UI를 업데이트 해야 할 필요가 생겼을 때, 이 변경사항은 먼저 Virtual DOM에 적용됩니다.

  2. 차이 비교: 변경된 Virtual DOM과 이전 Virtual DOM 사이의 차이점을 계산합니다. 이 과정을 'Diffing'이라고 하며, 이를 통해 실제로 변경된 부분만 파악할 수 있습니다.

  3. 배치 업데이트: 변경된 부분만을 실제 DOM에 배치적으로 업데이트합니다. 이러한 방식은 브라우저의 리플로우(reflow)와 리페인트(repaint)를 최소화하여 성능을 개선합니다.

  4. UI 렌더링: 최종적으로 사용자에게 보여지는 UI는 실제 DOM에 의해 렌더링됩니다.

컴포넌트

React에서 컴포넌트는 UI의 독립적이고 재사용 가능한 부분들을 캡슐화하는 데 사용됩니다.

컴포넌트의 특징

  • 재사용성: 컴포넌트는 독립적인 단위로 구성되어 있어, 다른 프로젝트나 애플리케이션에서도 재사용할 수 있습니다.

  • 캡슐화: 컴포넌트는 내부 로직을 숨기고, 인터페이스만을 제공하여 다른 컴포넌트와의 상호 작용을 단순화합니다.

  • 독립성: 각 컴포넌트는 독립적으로 작동하며, 다른 컴포넌트의 내부 상태에 직접적으로 접근하지 않습니다.


JSX(JavaScript XML)

JSX는 JavaScript와 XML, HTML을 합친 것이라 볼 수 있습니다.

JSX는 내부적으로 XML, HTML 코드를 JavaScript로 변환하는 과정을 거칩니다.

JSX를 사용하는 것이 필수는 아닙니다.
다만 JSX를 사용했을 때 생산성과 가독성이 올라가므로 사용하는 것이 좋습니다.

Injection Attacks을 방어 할 수 있습니다.

  • React DOM은 JSX에 포함된 모든 값을 렌더링하기 전에 이스케이프 처리합니다. 이는 JSX를 통해 전달되는 모든 값이 문자열로 변환되어 실행되기 전에 필터링된다는 것을 의미합니다.

코드 예제

  • JSX를 사용한 코드
const element = (
	<h1 className="greeting">
  		Hello, world!
  	</h1>
)
  • JSX를 사용하지 않은 코드
const element = React.createElement(
	'h1', 						// element의 유형입니다. (type)
    { className: 'greeting' }, 	// 요소에 전달할 속성들의 객체입니다. (props)
    'Hello, world!'				// 요소의 자식으로 들어갈 내용입니다. (children)
  	// 문자열일 수도 있고, 다른 React 요소들일 수도 있으며, 또는 이들의 배열일 수도 있습니다.
)
  • 컴파일 과정 후의 React 요소 객체를 나타냅니다.
const element = {
 	type: 'h1',	
  	props: {	
    	className: 'greeting',
      	children: 'Hello, world!'
    }
}

js는 스크립트 언어인데 왜 컴파일 과정을 거치지?

  • JavaScript는 전통적으로 인터프리터 언어이지만 현대적인 엔진에서는 JIT 컴파일을 포함한 복잡한 실행 과정을 거치며, JSX와 같은 확장 문법을 사용할 때는 해당 코드를 브라우저가 이해할 수 있는 JavaScript 코드로 "트랜스파일"하는 과정이 필요합니다.

JSX(JavaScript XML) 사용법

JSX에서는 {}를 사용하면 무조건 JavaScript 코드가 들어간다고 외워두는게 좋습니다.

React에서 Elements란?

React 앱을 구성하는 가장 작은 블록들을 말합니다.
Element는 원래 DOM Element를 뜻합니다.

React Elements와 DOM Elements의 차이

  • React Elements : DOM Elements의 가상표현
    React Elements는 실제 DOM에 직접적으로 매핑되지 않으며, React가 가상 DOM을 통해 실제 DOM과의 차이를 비교하고 필요한 최소한의 변경사항만을 적용할 수 있게 해줍니다.
    JavaScript 객체 형태로 존재하고 불변성을 가집니다.

JavaScript 객체 예시

{
  	type: 'button',
    props: {
    	className: 'bg-green',
        children: {
        	type: 'b',
            props: {
            	children: 'Hello, element!'
            }
        }
    }
}

실제로 랜더링 됐을 때 Element

<button class='bg-green'>
  <b>
  	Hello, element!
  <b>
</button>
  • DOM Elements : 실제 DOM 트리에 존재하는 HTML 엘리먼트를 나타내는 객체

React에서 Elements의 특징


Elements 렌더링하기

Root DOM node

<div id="root"></div> <!-- Root DOM node -->

이 코드는 모든 React 앱에 필수적으로 들어가는 코드입니다.
div 태그 안에 React Element들이 렌더링 됩니다.
div 태그 안에 있는 모든 것이 React DOM에 의해서 관리됩니다.

root div에 React Element를 렌더링하는 코드

const element = <h1>Hello</h1>;
ReactDOM.render(element, document.getElementById('root'));
// ReactDOM.render(React Element, HTML Element(DOM Element))
// React Element를 DOM Element에 렌더링합니다.

렌더링 된 Elements 업데이트하기

Element는 불변성을 가지기 때문에 다시 생성해야 합니다.

function tick() {
 	const element = (
    	<div>
      		<h1>Hello</h1>
      		<h2>현재 시간: {new Date().toLocaleTimeString()}</h2>
    	</div>
    );
  
  	ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000); // tick 함수를 1000ms마다 호출

Components란?

React에서 모든 페이지는 Component로 구성되어 있고, 하나의 Component는 또 다른 여러 개의 Component의 조합으로 구성될 수 있습니다.

즉, 레고 블록을 조립하듯 Component들을 모아서 조립하는 느낌입니다.

Component 이름은 항상 대문자로 시작해야합니다.
React는 소문자로 시작하는 컴포넌트를 DOM 태그로 인식합니다.

const element = <welcome name="홍길동"/>; // (X) HTML 태그로 인식
const element = <Welcome name="홍길동"/>; // (O) React Compenent로 인식

Components클래스 컴포넌트함수 컴포넌트 두 가지 유형으로 나뉩니다.

  • 함수 컴포넌트: 단순히 props를 입력받아서 렌더링할 요소를 반환하는 함수입니다.
    React Hooks를 사용하여 상태관리와 생명주기 기능을 구현할 수 있습니다.

  • 클래스 컴포넌트: React.Component를 상속받아 생성되며, render 메소드를 통해 렌더링할 요소를 반환합니다.

class Welcome extends React.Component{
  render() {
  	return <h1>안녕, {this.props.name}</h1>;
  }
}

React component는 개념적으로는 JavaScript의 함수와 비슷합니다.
일반적으로 JavaScript(또는 TypeScript) 클래스나 함수로 작성됩니다.

React component에서의 입력은 Props 이고 출력은 React element 가 됩니다.

Props?

Props는 properties(특성)의 줄임말로, Component에 데이터를 전달하는 방법입니다.

  • 읽기 전용: Component는 자신의 props를 수정할 수 없습니다.
function ex1(account, amount){
	account.total -= amount;	
  	// 입력으로 받은 파라미터의 account객체의 total값을 수정하였습니다.
  	// Props는 읽기 전용이기 때문에 이러한 방식이 불가능합니다.
}
  • 재사용성 증가: 동일한 component를 다양한 props 값을 넣어 재사용 할 수 있습니다.

props를 사용하는 방법은 이와 같습니다.

function Welcome(props) {
  return <h1>안녕하세요, {props.name}!</h1>;
}

function App() {
  return <Welcome name="홍길동" />;
}

위 예제에서 App Component는 Welcome Component에 name이라는 prop홍길동이라는 값으로 전달합니다.


0개의 댓글