Back to blog
Jul 24, 2024
4 min read

[번역] What is Reactivity?

React Beyond the Render - What is Reactivity?

원문 : https://playfulprogramming.com/posts/what-is-reactivity

숙련된 프론트엔드 엔지니어인 저는 다음과 같은 질문을 자주 받습니다.

“왜 React, Angular 또는 Vue와 같은 최신 프론트엔드 프레임워크를 사용하려고 하나요?”

이 주제에 대한 전체(무료) 책 이 있지만, 제 짧은 대답은 일반적으로 "Reactivity"입니다.

“Reactivity란 무엇인가요?”

간단히 말해 Reactivity란 자바스크립트 애플리케이션의 메모리에 있는 내용을 DOMHTML로 반영하는 기능입니다. 정적 HTML만 사용하여 웹사이트를 구축하는 경우 DOM에 대한 출력은 간단합니다.

<!-- index.html -->
<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>

문제는 출력에 상호작용을 도입하고자 할 때 시작됩니다.

다음과 같은 소규모 애플리케이션을 만들어 보겠습니다.

  1. 내부에 카운터가 있는 버튼이 있습니다.
  2. 버튼을 클릭할 때마다 카운터를 0에서 시작합니다.
  3. 버튼을 클릭할 때마다, 카운터에 1을 추가합니다.

이를 위해 몇 가지 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>

목록 추가하기

너무 나쁘지 않다면 난이도를 조금 더 높여 보겠습니다.

  1. 정렬되지 않은 목록 추가하기 (<ul/>)
  2. 개수가 늘어날 때마다 내부에 고유 문자열이 포함된 새 <li>를 추가합니다.

다음과 같이 보일 수 있습니다.

<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>

목록에서 항목 제거하기

좋아요! 열기가 뜨거워지고 있습니다! 마지막으로 한 가지 연습을 해보겠습니다:

  1. 카운트에서 1을 제거하는 버튼 추가
  2. 이 버튼을 누르면 목록에서 마지막 요소를 제거합니다.
<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>

와우! 복잡해졌죠?! 바로 그거죠?!

맞아요… 그래서 질문이 생겼습니다.

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

개수에 의존하는 다른 항목을 추가할 때마다 데이터는 변하지 않는 것을 알 수 있습니다.

대신 자바스크립트 상태를 해당 상태의 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>
	// 'count'가 변경되면 DOM이 자동 업데이트되는 마법의 지역
	let count = 0;
	addBtn.addEventListener('click', () => { count++; });
	removeBtn.addEventListener('click', () => { count--; });
</script>

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

이 더 멋진 코드 작성 방법은 이론적으로 가능할 뿐만 아니라 수백만 명의 개발자가 프론트엔드 프레임워크를 통해 널리 채택하고 있습니다.

프론트엔드 프레임워크의 몇 가지 예는 다음과 같습니다.

  • React
  • Vue
  • Angluar
// 예시는 React로만 표기합니다.
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>
	);
};

독자 여러분, 이것이 바로 Reactivity의 핵심 아이디어입니다.

자바스크립트에 저장된 상태를 어떻게 변경할 것인지에 집중하고 다른 메커니즘이 화면에 표시되는 방식을 추상화할 수 있도록 하는 것입니다.

이러한 메커니즘은 매우 다른 방법을 사용할 수도 있습니다!

예를 들어 각 프레임워크가 내부적으로 활용하는 방법은 다음과 같습니다.

프레임워크Reactivity MethodRendering Method
ReactExplicit Function CallsVDOM
AngularZone.jsIncremental DOM
VueProxiesVDOM

지금은 정말 괴짜 같은 시간입니다. 지금 이 말이 횡설수설처럼 들리더라도 기분 나빠하지 마세요.

결론

지금까지 반응성이란 무엇이며 왜 최신 프론트엔드 프레임워크를 사용하여 앱에서 이를 활용해야 하는지 살펴보았습니다.

다음 시간에는 “조정”이 무엇이며 오늘날 대부분의 React 및 Vue 프론트엔드 애플리케이션에 미치는 영향에 대해 이야기하겠습니다.