[React/번역] 반응성(Reactivity)이란 무엇인가? - 프론트엔드 프레임워크를 사용하는 이유

Bomin·2024년 1월 22일
3

[React]

목록 보기
4/5
post-thumbnail

이 글은 Corbin Crutchley의 What is Reactivity? 를 번역한 글입니다. 오역, 의역 있을 수 있습니다.

TL;DR

  • React같은 모던 프레임워크를 사용하는 이유는 반응성(Reactivity)때문이다.
  • 반응성이란 JavaScript 애플리케이션의 메모리 내용을 DOM에 HTML로 반영하는 기능이다.
  • React, Vue와 같은 모던 프레임워크를 사용하면 DOM에 바인딩되는 방식이 아닌,
  • JavaScript 데이터에 초점을 맞추고 코드를 작성할 수 있게 해준다.

What is Reactivity

프론트엔드 개발자라면 이런 질문을 자주 들어봤을 겁니다.

왜 React, Vue, Angular 같은 모던 프레임워크를 사용하나요?

"반응성(Reactivity)" 때문이라 대답할 수 있습니다.

그렇다면 반응성은 무엇일까요?

간단히 말해, 반응성은 자바스크립트 애플리케이션의 메모리 내용을 DOM에 HTML로 반영하는 기능입니다.

정적 HTML로만 웹사이트를 만드는 경우 DOM 출력은 간단합니다.

<main id="a">
	<ul id="b">
		<li id="c">Item 1</li>
		<li id="d">Item 2</li>
	</ul>
	<p id="e">Text here</p>
</main>
ww

문제는 인터랙티브(상호작용) 기능을 도입하려고 할 때 일어납니다.

소규모 애플리케이션을 만든다고 생각해봅시다:
- 내부에 카운터가 있는 버튼이 있습니다.
- 카운터는 0에서 시작합니다.
- 버튼을 클릭할 때마다 카운터가 1씩 증가합니다.

ww

이를 위해 먼저 HTML을 만들어봅시다:

<main>    
	<button id="add-button">Count: 0</button>  
</main> 

그 다음 자바스크립트를 추가하여 버튼이 동작하도록 만듭니다.

<script>
	let count = 0;
	const addBtn = document.querySelector('#add-button');
	addBtn.addEventListener('click', () => {
		count++;
		addBtn.innerText = `Count: ${count}`;
		});
</script>

List 구조 추가하기

괜찮네요. 그러면 조금 난이도를 높여 보겠습니다:

  • <ul> 로 리스트를 만들어봅시다.
  • count가 증가할 때마다 내부에 고유 문자열이 있는 새 <li> 추가하기
ww
이렇게 할 수 있겠죠?
<main>
	<button id="add-button">Count: 0</button>
	<ul id="list"></ul>
</main>
<script>
	let count = 0;
	
	const listEl = document.querySelector('#list');

	function makeListItem(innerText) {
		const li = document.createElement('li');
		li.innerText = innerText;
		listEl.append(li);
	}

	const addBtn = document.querySelector('#add-button');
	addBtn.addEventListener('click', () => {
		count++;
		addBtn.innerText = `Count: ${count}`;
		makeListItem(`List item: ${count}`);
	});
</script>

삭제 기능 추가하기

좋습니다! 이제 마지막 연습입니다:

  • count에서 1을 제거하는 버튼을 추가합니다.
  • 이 버튼을 누르면 리스트에서 마지막 요소를 제거합니다.
ww

로직 트리가 얼마나 복잡해져가는지 보이나요?

<main>
	<button id="add-button">Add one to: 0</button>
	<button id="remove-button">Remove one from: 0</button>
	<ul id="list"></ul>
</main>

<script>
	let count = 0;

	const listEl = document.querySelector('#list');

	function makeListItem(innerText) {
		const li = document.createElement('li');
		li.innerText = innerText;
		listEl.append(li);
	}

	function removeListItem() {
		listEl.lastChild.remove();
	}

	const addBtn = document.querySelector('#add-button');
	const removeBtn = document.querySelector('#remove-button');

	function updateBtnTexts() {
		addBtn.innerText = `Add one to: ${count}`;
		removeBtn.innerText = `Remove one from: ${count}`;
	}

	addBtn.addEventListener('click', () => {
		count++;
		updateBtnTexts();
		makeListItem(`List item: ${count}`);
	});

	removeBtn.addEventListener('click', () => {
	count--;
	updateBtnTexts();
	removeListItem();
	});
</script>

와! 정말 순식간에 복잡해졌네요, 그렇죠?!

네..그래서 질문이 생겼습니다:

더 간단해야 하지 않을까요?

count에 의존하는 다른 항목을 추가할 때, 데이터가 변경되지 않았다는 것에 집중해주세요.
대신, 자바스크립트 state를 해당 state의 DOM 표현에 붙이기 위해 점점 더 많은 복잡성을 추가해야 했습니다.

이 모든 '접착제(가져다 붙이기 위한 코드들)'를 제거하면 아주 간소화된 코드베이스가 남게 됩니다:

<main>
	<button id="add-button">Add one to: 0</button>
	<button id="remove-button">Remove one from: 0</button>
	<ul id="list"></ul>
</main>
	<script>
	// Magical land where `count` changes auto-update the DOM
	let count = 0;

	addBtn.addEventListener('click', () => {
	count++;
	});

	removeBtn.addEventListener('click', () => {
		count--;
	});
	</script>
ww

얼마나 많은 줄들이 사라졌는지 보세요!

이보다 더 좋은 코드 작성 방법은 이론적으로 가능할 뿐만 아니라, 수많은 개발자가 프론트엔드 프레임워크를 통해 채택하고 있습니다.

  • React
  • Vue
  • Angular
    와 같은 프레임워크를 사용하면 DOM에 바인딩되는 방식이 아닌 자바스크립트의 데이터에 초점을 맞춘 코드를 작성할 수 있습니다.
const App = () => {
	const [count, setCount] = useState(0);

	return (
	<div>
		<button onClick={() => setCount(count + 1)}>
			Add one to: {count}
		</button>
		<button onClick={() => setCount(count - 1)}>
			Remove one from: {count}
		</button>
		<ul>
			{Array.from({ length: count }).map((_, i) => (
				<li>List item {i}</li>
			))}
		</ul>
	</div>
	);
};

이것이 바로 반응성의 핵심 아이디어입니다. 자바스크립트에 저장된 상태를 어떻게 변경할 것인지에 집중할 수 있게 해주고, 다른 메커니즘을 통해 화면에 표시되는 방식을 추상화 할 수 있게 해줍니다.

예를 들어 각 프레임워크가 화면 표시 방법에 대해 내부적으로 활용하는 메커니즘은 다음과 같습니다:

FrameworkReactivity MethodRendering Method
ReactExplicit Function CallsVDOM
AngularZone.jsIncremental DOM
VueProxiesVDOM

결론

지금까지 반응성이란 무엇이고, 오늘날 앱에서 반응성을 활용하기 위해 모던 프론트엔드 프레임워크를 사용해야하는 이유에 대해 살펴보았습니다.
다음 시간에는 "Reconciliation"이 무엇이며 오늘날 대부분의 React 및 Vue 프론트엔드 애플리케이션에 어떤 영향을 미치는지에 대해 이야기하겠습니다.

profile
Frontend-developer

0개의 댓글