
오늘은 부트캠프에서 바닐라 JS만으로 프로젝트를 진행한 1차 프로젝트 때와의 차이점으로 React를 활용하였을 때 느꼈던 경험에 대해 적어보고자 합니다! 수업을 진행하며, 그리고 프로젝트를 진행하며 배우고 느끼게 된 "아~ 이건 이렇게 다르구나!"라고 생각했던 포인트들을 정리해보려고 합니다!
바닐라 JavaScript만으로 만들 수 있는 건 참 많죠! 어떻게 보면 못 만드는 게 없다고 할 수 있겠습니다..!
저도 처음에는 바닐라 JS로 간단한 TODO 앱, 모달, 탭 UI 같은 걸 만들면서 많은 걸 배웠었습니다.
그런데 점점 프로젝트가 커지다 보니, 이런 생각이 들더라구요...
"이거 상태 관리 너무 힘든데...?"
"코드가 점점 꼬여간다..."
"파일 나누기도 애매하고, 재사용도 어렵고... 이 코드 또 복붙 해...?"
등등...
그래서 자연스럽게 이런 불편함을 해소할 수 있는 React에 관심을 갖게 되었고, 배우게 되었습니다!
따라서 오늘 글은 리액트를 배우며 그냥 바닐라 JS를 사용할 때 보다 이런 때 더 편리했다..! 하는 부분들에 대해 간단하게 짚어보고자 합니다! 그럼 가볼까요!
✅ 1. UI를 만드는 방식이 완전히 달라졌다!
처음 바닐라 JS로 개발할 땐, HTML 파일에 버튼을 만들고 자바스크립트에서 getElementById 같은 걸로 DOM을 찾아 이벤트를 붙였습니다.
<!-- index.html -->
<div id="app">
<button id="btn">클릭</button>
</div>
// script.js
document.getElementById('btn').addEventListener('click', () => {
alert('클릭됨!')
})
위 코드와 같이 HTML은 HTML대로, JS는 JS대로 코드를 작성했죠.
디자인을 바꾸려면 CSS도 따로 수정해야 하고, 뭔가 UI 조각을 여러 군데에 재사용하려면 복사, 붙여 넣기 밖에 방법이 없었습니다!
❗ 물론 lit 같은 라이브러리를 사용하면 바닐라 JS에서도 컴포넌트 방식으로 개발할 수 있어요! HTML 템플릿을 JS 안에서 다루고, 컴포넌트 단위로 캡슐화할 수도 있죠.
다만, 생태계나 도구 지원, 그리고 상태 관리, 라우팅, 빌드 도구와의 연계 등에서 React는 훨씬 더 잘 다듬어진 환경이라 실무에서 더 자주 쓰이는 것이라는!
그런데 React에서는 UI를 만드는 방식 자체가 달랐습니다!
하나의 기능 단위를 "컴포넌트"로 만들어서, HTML + JS + (필요하면 CSS까지)를 한 곳에 같이 묶을 수 있습니다.
아래 코드와 같이요!
function MyButton() {
return <button onClick={() => alert('클릭됨!')}>클릭</button>
}
이런 문법을 JSX라고 하는데 처음엔 당연히 낯설었습니다.
"HTML 안에 자바스크립트를 넣는다고?" 하고 혼란스럽기도 했고, JSX 문법도 생소했습니다.
📌 하지만 쓰면 쓸수록 느끼는 장점들
- UI를 하나의 단위로 나눌 수 있다 → 예: 버튼, 카드, 헤더
- 필요한 기능을 만들고 또 재사용하기가 너무 쉬움
- 여러 명이 나눠서 작업할 때도, 컴포넌트 단위로 나누니까 협업이 훨씬 편했다
- 피드백을 받은 부분이 있다면 그 부분만 수정하면 되니까 유지보수도 수월해짐!
바닐라 JS로 코드를 작성했던 때에는 HTML + CSS + JS를 따로따로 다뤘다면, React에서는 이걸 기능 단위로 묶어서 생각하게 되어서 코드를 읽기도, 관리하기도 훨씬 쉬워졌다고 느꼈습니다~
✅ 2. 상태(state) 관리가 깔끔해졌다!
바닐라 JS에서 상태를 관리하려면, 전역 변수나 DOM 요소에 값을 저장하고 직접 갱신해야 했어요. 예를 들면
let count = 0;
const btn = document.getElementById('btn');
const display = document.getElementById('display');
btn.addEventListener('click', () => {
count += 1;
display.textContent = count;
});
위 코드와 같이 직접 DOM 요소를 찾아서 값을 바꿔줘야 했죠.
하지만 React에서는 useState 훅을 사용해서 상태를 다룰 수 있고, 이렇게 하면 훨씬 간단해집니다.
심지어 상태가 바뀌면 자동으로 UI가 업데이트돼요!
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
📌 느낀점
- 바닐라 JS에서는 내가 DOM을 직접 조작해야 했는데, React에서는 상태만 바꾸면 UI가 자동으로 바뀜
- DOM을 직접 조작하지 않고도 화면이 자동으로 바뀌어서 편함
- 상태 변화에 따라 UI가 알아서 리렌더링 되는 게 신기하고 강력함
- 여러 개의 상태를 독립적으로 관리할 수 있어 복잡한 UI에서도 깔끔한 코드 유지 가능
- 이게 진짜 편하고, 복잡한 UI일수록 장점이 커짐!!!
✅ 3. 조건부 렌더링과 리스트 반복이 편해짐
바닐라 JS에서는 조건에 따라 DOM을 추가하거나, 반복해서 HTML을 만들어야 할 때 보통 innerHTML로 문자열을 만들었어요
const items = ['🍎', '🍌', '🍇'];
const listEl = document.getElementById('list');
listEl.innerHTML = items.map(item => `<li>${item}</li>`).join('');
하지만 바닐라 JS에서는 조건이 많아질수록 innerHTML로 문자열을 이어 붙이는 방식이 번거롭고, 괄호와 따옴표가 섞이다 보면 실수도 많아지고 코드의 가독성도 떨어집니다..
예를 들어, 리스트 안에 조건부로 특정 항목을 제외하고 렌더링 하려 할 때, HTML 문자열로 처리하는 건 쉽지 않겠죠.
하지만 React에서는 JSX 문법을 통해 자바스크립트 표현식을 그대로 HTML처럼 쓸 수 있기 때문에 조건부 렌더링이나 리스트 반복이 훨씬 안전하게 작성할 수 있습니다!
조건이 복잡해져도 삼항 연산자나 논리 연산자를 조합해서 직관적으로 표현할 수 있고, 반복문도. map()을.map() 그대로 사용할 수 있어 로직과 UI의 연결이 명확해지죠.
function FruitList({ fruits }) {
if (fruits.length === 0) return <p>과일이 없어요!</p>;
return (
<ul>
{fruits.map(fruit => (
<li key={fruit}>{fruit}</li>
))}
</ul>
);
}
📌 느낀점
- JSX 안에서 JS 표현식이 가능하니까 훨씬 직관적이에요
- 조건부 렌더링도 조건 && <div>...</div> 이런 식으로 깔끔하게 가능해서 너무 좋아요
- 템플릿 문자열을 조작할 필요가 없어서 실수도 줄고 가독성도 좋아져요!
✅ 4. props를 통해 컴포넌트를 유연하게 만들 수 있음!
리액트를 사용하게 되면서 가장 신세계라고 느꼈던 부분인데요! 리액트를 사용하면 props를 통해 컴포넌트를 유연하게 제작할 수 있습니다.
바닐라 JS에서는 HTML 요소를 동적으로 생성하거나 수정할 때 document.createElement나 innerHTML을 사용합니다. 하지만 이런 방식은 UI를 재사용하는 데 어려움이 있어, 반복적인 코드가 많아지고 코드 유지보수가 번거로웠습니다.
예를 들어, 특정 요소를 여러 번 사용하려면 그때그때 DOM을 직접 조작하고, 내용이 달라질 때마다 반복적으로 HTML을 갱신해야 했습니다. 이런 방식은 효율적이지 않고 큰 프로젝트일수록 코드가 점점 복잡해지게 만들었죠..
하지만 React에서는 컴포넌트라는 개념을 사용해서, UI를 재사용할 수 있는 작은 단위로 쪼갭니다. 이때, props(속성)을 이용해 데이터만 다르게 전달하면, 같은 컴포넌트를 다양한 데이터에 맞게 유연하게 재사용할 수 있습니다! 이게 리액트의 엄청난 장점이죠!
컴포넌트는 기본적으로 함수처럼 동작하고, props는 그 함수에 전달되는 '매개변수'라고 생각하면 좀 더 쉽게 이해할 수 있습니다.
function Greeting({ name }) {
return <h1>안녕하세요, {name}님!</h1>;
}
<Greeting name="주연" />
<Greeting name="선호" />
위 예제에서 GreetingGreeting이라는 컴포넌트 하나로 name이라는 props만 바꿔서 완전히 다른 UI처럼 출력할 수 있어요.
이는 마치 하나의 템플릿에 다른 데이터를 넣어서 다양한 결과를 만들어내는 것과 같죠!
📌 느낀 점
- 함수처럼 컴포넌트를 만들고, props를 통해 다양한 데이터를 넣어 재사용할 수 있어 생산성과 유지보수성이 높아짐
- 하나의 컴포넌트로 여러 상황을 처리할 수 있어 중복 코드를 줄이고, 로직을 더 깔끔하게 구성할 수 있음
✅ 5. 배운 점 + 깨달은 점
- 상태 변화에 따라 UI가 자동으로 바뀌는 흐름이 너무 강력하다
- 바닐라 JS는 ‘어떻게 동작시킬지’에 집중했다면
→ React는 ‘상태 기반으로 UI를 설계하는 사고’를 키워줌 - 컴포넌트 기반 구조 덕분에 코드의 재사용성과 유지보수가 크게 향상됨
- 그리고 무엇보다도... 처음엔 어렵지만, 하면 할수록 편해진다!! 익숙해지면 된다!!
✅ 정리하며
바닐라 JS로 웹앱을 만들면서 DOM 조작, 이벤트 바인딩, 구조 설계 등 기본기! 말 그대로 코어를 많이 익혔다면,
React는 그걸 더 구조화하고 더 편하게 만드는 도구라고 느꼈어요!
코어 JS를 열심히 공부해 보면 React의 근간은 확실히 JavaScript구나 깨닫게 되면서 바닐라 JS의 코어 내용에 대한 공부에 대한 욕심도 더 생기게 되는 것 같습니다.
모든 것은 JS다..라는 깨달음 이랄까요?ㅎㅎ
오늘 글은 여기까지 입니다. 좋은 아침, 좋은 낮, 좋은 밤, 좋은 새벽 보내시고, 맛있는 밥 드시고, 좋은 음악 들으시고, 좋은 글 읽으시길 바라요 안녕~

'🖥️개발 > 🐋React' 카테고리의 다른 글
[리액트] props (0) | 2025.03.08 |
---|---|
[Zustand] Zustand란? 리액트에서 Zustand를 사용하는 이유 (0) | 2025.02.23 |
[React] ref란? (0) | 2025.02.16 |
[React] 리액트의 단방향 데이터 흐름 (One-way Data Flow) (0) | 2025.02.02 |
[React] <input>과 <label>은 함께 써요! with. React.useId Hook (0) | 2025.01.26 |