반응형

리액트 컴포넌트의 기본 개념 완전 정복하기

여러분, 리액트 입문하려고 검색하다가
"컴포넌트"라는 단어에 자꾸 막히신 적 있지 않으셨나요?
도대체 그게 뭐길래 이렇게 중요할까요?



안녕하세요,

이번 글에서는 리액트의 핵심 개념 중 하나인 컴포넌트(Component)에 대해 아주 쉽게, 그리고 직관적으로 설명해 드릴 거예요.
함수형 vs 클래스형? Props와 State는 또 뭔데? 이런 의문들, 여기서 전부 해결해 드릴게요!

지금부터 저와 함께 찬찬히, 하나씩 배워봅시다. 😄

1. 컴포넌트란 무엇인가요? 🤔

리액트에서 컴포넌트(Component)는 웹 페이지를 이루는 가장 작은 단위입니다.
우리가 눈으로 보는 버튼, 텍스트, 이미지, 카드 같은 것들이 바로 이 컴포넌트들로 구성돼 있어요.

 

정확히 말하면, 하나의 UI 요소를 독립적인 모듈로 나누어 관리할 수 있게 해주는 것이 바로 컴포넌트입니다.

🧠 왜 컴포넌트가 중요할까요?

  • 재사용성 향상:
  • 한 번 만든 컴포넌트를 다른 곳에서도 재사용할 수 있어요.
  • 유지보수가 쉬워짐:
  • 각 컴포넌트는 독립적으로 동작하므로 수정이 편리해요.
  • 테스트 용이:
  • 독립적인 단위라서 테스트 작성도 수월하답니다.

컴포넌트 예시: 쇼핑몰의 상품 카드

예를 들어 볼까요?

쇼핑몰 사이트를 떠올려보세요. 상품 리스트 화면에는 여러 개의 카드가 나열되어 있을 거예요.
각 카드에는 상품명, 이미지, 가격, 찜 버튼 같은 것들이 들어 있죠. 이걸 하나의 컴포넌트로 만들 수 있어요!

 

이렇게 하나의 UI 단위를 컴포넌트로 만들어 놓으면, 이후에 다른 페이지나 서비스에서도 복붙처럼 재활용할 수 있어서 정말 유용해요!

📋 컴포넌트란 이런 것!

구분 내용
정의 UI를 구성하는 독립적이고 재사용 가능한 단위
장점 재사용성, 유지보수 용이, 테스트 편리
실전 예시 상품 카드, 버튼, 입력 폼 등 다양한 UI 구성

 

여기까지가 리액트 컴포넌트의 정체에 대한 기본 설명이었어요!

다음 챕터에서는 실전 코드 예제를 통해 컴포넌트를 직접 만들어보며 더 깊이 이해해 볼게요. 😊

 

2. 함수형 컴포넌트 실전 예제 🧩

리액트에서 가장 많이 쓰이는 컴포넌트 형태는 바로 함수형 컴포넌트입니다.
ES6 이후 등장했고, 특히 React Hooks가 추가되면서 완전 대세로 자리잡았죠!

🧪 간단한 상품 카드 예제

한 번 코드를 같이 볼까요?

아래는 상품명을 보여주고 좋아요(Like) 버튼이 있는 간단한 컴포넌트입니다.

import React, { useState } from 'react';

function ProductCard({ name, price }) {
  const [liked, setLiked] = useState(false);

  return (
    <div>
      <h3>{name}</h3>
      <p>Price: ${price}</p>
      <button onClick={() => setLiked(!liked)}>
        {liked ? 'Unlike' : 'Like'}
      </button>
    </div>
  );
}

export default ProductCard;

🧠 코드 해석

  • useState를 통해 liked라는 상태값을 생성
  • 버튼 클릭 시 setLiked를 호출하여 상태를 반전시킴
  • 상태가 바뀌면 리렌더링되어 'Like' 또는 'Unlike'가 즉시 반영됨

정말 신기하지 않나요? 단 몇 줄의 코드만으로 사용자 반응에 따라 UI가 바뀌다니...
이게 바로 리액트 함수형 컴포넌트의 매력이에요!

📌 함수형 컴포넌트 특징 정리

항목 설명
형태 일반 자바스크립트 함수 형태
상태 관리 useState 훅 사용
라이프사이클 useEffect 등 훅으로 처리
장점 가볍고 읽기 쉬움, 훅으로 다양한 기능 확장 가능

 

이제 함수형 컴포넌트가 어떤 식으로 동작하는지 감이 좀 오셨죠? 😄

다음 단계에서는 클래스형 컴포넌트와 비교해 보면서 차이를 더 분명하게 알아볼 거예요.

 

3. 클래스형 컴포넌트도 아직 유효할까요? 🏛

요즘 리액트 개발자들 사이에선 함수형 컴포넌트가 대세지만, 클래스형 컴포넌트도 여전히 존재합니다.
특히 옛날 코드나 레거시 프로젝트를 다룰 땐 꼭 알아둬야 해요.

React 16.8 이전까지는 클래스형 컴포넌트가 기본이었거든요.

📦 클래스형 컴포넌트 예제

아까 함수형으로 만들었던 ProductCard를 이번엔 클래스 기반으로 다시 만들어볼게요.

import { Component } from 'react';

class ProductCard extends Component {
  constructor(props) {
    super(props);
    this.state = { liked: false };
  }

  toggleLike = () => {
    this.setState({ liked: !this.state.liked });
  };

  render() {
    return (
      <div>
        <h3>{this.props.name}</h3>
        <p>Price: ${this.props.price}</p>
        <button onClick={this.toggleLike}>
          {this.state.liked ? 'Unlike' : 'Like'}
        </button>
      </div>
    );
  }
}

export default ProductCard;

🧠 클래스형 방식 요점 정리

  • constructor()에서 상태 this.state 초기화
  • 이벤트 핸들러는 보통 화살표 함수(=>)로 바인딩 처리
  • UI 출력은 render() 메서드 안에서 처리

🆚 함수형 vs 클래스형 비교

구분 함수형 컴포넌트 클래스형 컴포넌트
문법 자바스크립트 함수 ES6 클래스
상태 관리 useState this.state + setState()
라이프사이클 useEffect componentDidMount
사용 추천 현대 리액트 개발 전반 레거시 유지보수나 학습용

 

정리하자면,

클래스형 컴포넌트는 여전히 중요하지만,

현재 실무에서는 함수형이 거의 대부분이니 초보자분들은 함수형 중심으로 익히는 게 좋아요!

 

4. JSX와 컴포넌트 구조 🧬

리액트 컴포넌트를 제대로 이해하려면, JSX 문법과 컴포넌트의 구조에 대한 이해는 필수예요.

JSX는 JavaScript 내부에서 HTML을 작성할 수 있게 도와주는 리액트 전용 문법이에요.

🔤 JSX란?

JSX는 JavaScript XML의 줄임말로, XML(HTML)과 비슷한 문법을 JavaScript 코드 안에 바로 작성할 수 있게 해줘요.

function WelcomeMessage() {
  return <h1>Welcome to My Website!</h1>;
}

 

이처럼 JSX는 HTML처럼 생겼지만, 실제론 JavaScript 코드라는 점!

그래서 문법적으로도 JS 규칙을 따라야 해요.

예를 들어 class는 className으로 써야 하죠.

🔗 Props로 데이터 전달하기

컴포넌트끼리 데이터를 전달할 땐 Props(속성)를 사용합니다.

부모 컴포넌트가 자식 컴포넌트에 값을 전달하는 역할이죠!

// 부모 컴포넌트
function App() {
  return <ProductCard name="Laptop" price={999} />;
}

// 자식 컴포넌트
function ProductCard(props) {
  return (
    <div>
      <h3>{props.name}</h3>
      <p>Price: ${props.price}</p>
    </div>
  );
}

 

여기서 중요한 점은 Props는 읽기 전용이라는 거예요. 컴포넌트 안에서 직접 수정할 수는 없어요.

📈 State로 동적인 값 관리하기

Props는 부모 → 자식으로 전달하는 고정값이라면, State는 컴포넌트 자체에서 변화하는 값이에요.

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>현재 카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>증가</button>
    </div>
  );
}

 

이 컴포넌트는 클릭할 때마다 상태(count)가 변하면서 UI가 즉각 반응해요.
이게 바로 리액트의 진짜 매력이죠!

📌 JSX & 컴포넌트 구조 요약

개념 설명
JSX JS 안에 HTML처럼 작성할 수 있는 리액트 문법
Props 부모 컴포넌트가 자식에게 전달하는 읽기 전용 값
State 컴포넌트 내부에서 관리되는 동적 데이터

 

여기까지가 JSX와 컴포넌트의 기본 구조였어요! 이제 마지막으로 React Hooks를 활용해 라이프사이클까지 정리해 볼게요. 💫

 

6. React Hooks로 라이프사이클 관리하기 🔁

React에서 컴포넌트는 생성 → 업데이트 → 소멸이라는 생명주기(Lifecycle)를 갖습니다.

클래스형 컴포넌트에서는 이 생명주기를

componentDidMount, componentDidUpdate, componentWillUnmount 등 메서드로 관리했는데요.

함수형 컴포넌트에서는 useEffect라는 Hook 하나로 라이프사이클을 모두 컨트롤할 수 있어요!

⏱ 라이프사이클이란?

  • Mount: 컴포넌트가 처음 렌더링될 때
  • Update: 상태나 Props가 바뀌어 다시 렌더링될 때
  • Unmount: 컴포넌트가 화면에서 사라질 때

💡 useEffect 기본 사용법

import { useState, useEffect } from 'react';

function Timer() {
  const [time, setTime] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setTime(prev => prev + 1);
    }, 1000);

    return () => clearInterval(interval); // 언마운트 시 정리
  }, []);

  return <p>경과 시간: {time}초</p>;
}

 

위 예제에서는 setInterval을 이용해서 1초마다 time을 증가시키고 있고요.
return 안의 함수는 컴포넌트가 사라질 때 실행돼서 타이머를 정리해줍니다.

이걸 정리(clean-up) 함수라고 불러요!

🧭 useEffect 두 번째 인자

패턴 설명
useEffect(fn, []) Mount 시 한 번만 실행됨
useEffect(fn, [state]) 해당 값이 변경될 때마다 실행됨
useEffect(fn) 모든 리렌더링마다 실행됨

 

이렇게 useEffect는 조건에 따라 다양한 방식으로 리액트 생명주기를 제어할 수 있어서 정말 유용해요!

✅ 정리: 리액트 훅과 라이프사이클

  • 함수형 컴포넌트의 생명주기 처리는 useEffect 하나로 가능!
  • useEffect(fn, [])은 컴포넌트 마운트 시 한 번만 실행됨
  • return 문 안에 정리(clean-up) 코드를 작성해 언마운트 처리

이제 여러분은 컴포넌트의 생성과 파괴까지 제어할 수 있는 리액트 고수가 되어가고 있어요! 👏

다음은 마지막으로 전체 내용을 요약하며 마무리해볼게요.

 

🎯 컴포넌트 개념, 이제 어렵지 않죠?

여기까지 따라오신 여러분, 정말 대단하세요! 👏

처음엔 조금 낯설고 어렵게 느껴졌을지 몰라도, 지금쯤이면 리액트 컴포넌트의 구조와 사용법이 꽤 익숙해졌을 거예요.

다시 한번 핵심만 정리해볼게요.

  • 컴포넌트는 UI의 최소 단위이며, 재사용성과 유지보수성을 높여줍니다.
  • 함수형 컴포넌트가 요즘 대세이며, Hooks를 통해 상태와 생명주기를 제어할 수 있어요.
  • Props는 외부에서 받는 값, State는 내부에서 변화하는 값이에요.
  • JSX 문법을 통해 JavaScript 안에서 HTML처럼 코드를 작성할 수 있어요.

이제 여러분은 리액트 컴포넌트를 제대로 이해한 거예요!

다음 단계로 넘어가기 전에, 간단한 프로젝트나 미니 앱을 직접 만들어보면서 복습해보는 걸 추천드려요.

실습이 최고의 선생님입니다! 😉

반응형
반응형

styled-components로 리액트 스타일링하기
: CSS-in-JS의 모든 것

여러분!
리액트 개발하면서 스타일 때문에 머리 아파본 적 있으신가요?
특히 CSS 충돌 문제… 정말 스트레스죠!

 

안녕하세요, 여러분! 😄
오늘은 React에서 스타일을 보다 효율적으로 관리할 수 있는 방법, 바로 styled-components에 대해 이야기해보려 해요.

 

웹 개발 환경이 점점 복잡해지고, CSS 관리가 머리 아픈 일이 되어버렸죠.

특히 리액트처럼 컴포넌트 기반으로 구조화된 프로젝트에서는 스타일의 지역화, 재사용성, 조건부 적용 같은 요소들이 점점 중요해지고 있습니다.

기존의 전역 스타일 방식은 충돌과 유지보수에 취약했고, 이를 해결하기 위해 등장한 것이 CSS-in-JS라는 패러다임입니다.

이 방식 중 대표적인 도구가 바로 styled-components죠.

이번 포스팅에서는 styled-components가 무엇인지, 어떻게 쓰는지, 그리고 진짜 현장에서 어떻게 활용하면 좋은지 실전 예제 중심으로 알아보겠습니다!

1. CSS-in-JS란 무엇인가?

CSS-in-JS는 말 그대로 CSS를 JavaScript 안에서 작성하는 스타일링 기법을 말합니다.

즉, 스타일을 별도의 CSS 파일로 분리하지 않고 JS 파일 내에서 함께 작성함으로써, 스타일과 컴포넌트의 결합도를 높이는 것이죠.

📌 CSS-in-JS의 주요 특징

  • 스타일과 컴포넌트를 함께 관리하므로 유지보수가 쉬움
  • 동적 스타일링이 가능 – props, 상태값 등을 활용하여 실시간으로 스타일 변경
  • CSS 클래스 이름 충돌 없음 – 고유 클래스명이 자동 생성됨

예전에는 CSS 파일이 점점 커지면서 어떤 클래스가 어디에 영향을 주는지 파악하기 힘들었죠.

그래서 스타일 충돌이 자주 발생했고, 컴포넌트 단위의 분리된 스타일 관리가 절실해졌습니다.

바로 이 문제를 해결한 게 CSS-in-JS입니다.

리액트 같은 컴포넌트 기반 개발 환경에 딱 맞는 스타일링 방식이죠!

 

💡정리하자면,

CSS-in-JS는 단순한 문법 변화가 아니라 UI 개발 방식의 패러다임 변화라고 볼 수 있어요.

개발자와 디자이너 모두에게 더 나은 협업 경험을 제공하는 스타일링 전략이죠.

 

 

2. styled-components 소개 및 사용법

styled-components는 CSS-in-JS 패러다임을 대표하는 라이브러리 중 하나로,

컴포넌트 기반 스타일링을 가장 직관적이고 효율적으로 구현할 수 있게 해줍니다.

이 라이브러리를 사용하면 JS 안에서 템플릿 리터럴(``)로 CSS 코드를 작성하고, 이를 실제 리액트 컴포넌트로 변환할 수 있어요.

🚀 styled-components의 장점

  • 컴포넌트 단위로 스타일 캡슐화되어 전역 스타일 충돌 걱정 없음
  • props 기반의 동적 스타일링이 매우 자연스럽고 강력함
  • 재사용 가능한 스타일 컴포넌트 작성 가능 – 코드 일관성 ↑

🧪 사용 예제

import styled from 'styled-components';

const Button = styled.button`
  font-size: 1rem;
  color: white;
  background-color: ${props => props.primary ? 'blue' : 'gray'};
  padding: 10px;
  border: none;
  border-radius: 5px;
  cursor: pointer;

  &:hover {
    background-color: ${props => props.primary ? 'darkblue' : 'darkgray'};
  }
`;

const App = () => (
  <div>
    <Button primary>Primary Button</Button>
    <Button>Default Button</Button>
  </div>
);

보시다시피 Button이라는 스타일 컴포넌트를 만들고, props(primary)에 따라 배경색을 다르게 적용하고 있어요.

:hover 같은 CSS 의사 클래스도 그대로 사용할 수 있어서 훨씬 직관적이고 가독성이 좋습니다.

 

💬 팁!

팀 단위 프로젝트에서는 버튼이나 카드 컴포넌트처럼 재사용 가능한 UI 요소를 styled-components로 만들어두면 코드 퀄리티와 생산성이 모두 올라갑니다!

 

 

3. props를 이용한 동적 스타일링

styled-components의 가장 큰 장점 중 하나는 props를 활용한 동적 스타일링입니다.

상태값이나 외부 데이터에 따라 스타일을 실시간으로 바꿀 수 있다는 뜻인데요,

조건부 렌더링보다 훨씬 더 직관적인 방식으로 스타일을 다룰 수 있어요.

🧪 예제: 상태값으로 색상 변경하기

import styled from 'styled-components';
import React from 'react';

const Title = styled.h1`
  font-size: 2rem;
  color: ${props => props.isActive ? 'green' : 'red'};
`;

const App = () => {
  const [isActive, setIsActive] = React.useState(false);

  return (
    <div>
      <Title isActive={isActive}>Styled Components!</Title>
      <button onClick={() => setIsActive(!isActive)}>
        Toggle
      </button>
    </div>
  );
};

이 코드를 실행하면 버튼 클릭 시마다 제목의 색상이 초록색 또는 빨간색으로 전환됩니다. 굳이 클래스 이름을 바꾸거나 별도 조건문 없이도 스타일을 깔끔하게 조절할 수 있다는 점에서 매우 유용하죠.

💡 이런 상황에 딱!

  • 버튼 활성화 여부에 따라 색상 변경
  • 상태 메시지에 따라 배경 또는 글자색 변경
  • props로 테마 색상, 크기, 간격 등을 조정할 때

결론적으로, styled-components의 props 기능을 활용하면 스타일과 로직이 자연스럽게 결합된 깔끔한 코드를 만들 수 있어요. 유지보수도 편하고 확장성도 뛰어납니다!

 

 

4. 조건부 스타일링 비교: 전통 방식 vs styled-components

리액트에서는 조건부 스타일링을 여러 방식으로 구현할 수 있습니다.

대표적으로는 전통적인 CSS 클래스 방식styled-components 기반의 조건부 스타일링이 있는데요,

각각 어떤 차이가 있을까요?

🧾 전통적인 CSS 클래스 방식

일반적인 방법은 className을 조건에 따라 변경하고, 해당 클래스에 스타일을 정의하는 것입니다.

/* App.css */
.active {
  background-color: green;
}
.inactive {
  background-color: red;
}
// App.js
import './App.css';

const App = () => {
  const isActive = true;

  return (
    <div className={isActive ? 'active' : 'inactive'}>
      조건부 스타일 적용
    </div>
  );
};

단점: 클래스 이름을 신경 써야 하고, CSS 파일이 커질수록 관리가 복잡해져요.

🎨 styled-components 방식

같은 기능을 styled-components로 구현하면 이렇게 됩니다:

import styled from 'styled-components';
import React from 'react';

const Box = styled.div`
  width: 100px;
  height: 100px;
  background-color: ${props => props.isActive ? 'green' : 'red'};
`;

const App = () => {
  const [isActive, setIsActive] = React.useState(false);

  return (
    <div>
      <Box isActive={isActive} />
      <button onClick={() => setIsActive(!isActive)}>Toggle Color</button>
    </div>
  );
};

장점: 스타일과 로직이 한눈에 보이며, 유지보수가 훨씬 편해집니다.

💡 정리하면?

방식 장점 단점
전통 CSS 클래스 ✔️ 간단하고 익숙함
✔️ 별도 도구 없이 사용 가능
❌ 클래스 충돌 위험
❌ 유지보수 복잡
styled-components ✔️ props 기반 조건부 스타일
✔️ 코드 가독성 및 재사용성↑
❌ 학습 필요
❌ 런타임 스타일 처리로 초기 렌더링 성능 미세 영향

5. 실무에서의 styled-components 활용 팁

styled-components는 단순한 스타일링 도구를 넘어,

디자인 시스템을 구성하거나 UI 컴포넌트를 효율적으로 관리할 수 있게 해주는 강력한 무기입니다.

아래에 실무에서 바로 적용할 수 있는 팁들을 정리해 보았어요!

🧰 styled-components 실전 팁

  • 컴포넌트 네이밍 규칙 통일
  • - 파일명, 컴포넌트명에 Styled 접두사 사용: StyledButton.js, StyledWrapper
  • 테마 설정과 함께 사용하기
  • - ThemeProvider를 활용하면 색상, 폰트, 여백 등을 일관되게 관리할 수 있어요.
  • 조건부 스타일은 최소화
  • - props를 너무 많이 주면 컴포넌트 복잡도가 올라가므로, 로직이 복잡해지기 전에 구조 분리 고려!
  • 스타일 상속 활용
  • - 공통 스타일을 만들고, styled(기존컴포넌트)로 쉽게 확장할 수 있어요.

💬 예시: ThemeProvider 사용

// theme.js
export const theme = {
  colors: {
    primary: '#007bff',
    secondary: '#6c757d',
  },
};
// App.js
import { ThemeProvider } from 'styled-components';
import { theme } from './theme';

<ThemeProvider theme={theme}>
  <App />
</ThemeProvider>
// StyledButton.js
const StyledButton = styled.button`
  background-color: ${props => props.theme.colors.primary};
  color: white;
`;

ThemeProvider를 활용하면 전체 프로젝트에 일관된 디자인 토큰을 적용할 수 있어요.

디자인 시스템 만들 때도 정말 유용하답니다!

 

6. 마무리 🎯

지금까지 styled-components와 CSS-in-JS의 개념부터 사용법, 실전 활용 팁까지 함께 살펴보았습니다.

이 방식은 단순히 코드 스타일링 방법을 넘어서, 유지보수성과 확장성을 동시에 잡을 수 있는 진화된 스타일링 전략입니다.

특히 동적 스타일링, 조건부 렌더링, 컴포넌트 재사용이 중요한 프로젝트라면 styled-components를 적극 추천드려요.

디자인 시스템 구축 시에도 강력한 무기가 되어 줄 겁니다.

처음에는 다소 낯설게 느껴질 수 있지만, 직접 사용해 보면 그 강력함에 금방 익숙해지실 거예요.

더 깔끔한 코드, 더 유지보수하기 쉬운 구조를 원하신다면 지금 바로 도입해보세요!

 

💬 오늘의 핵심 정리
✔ styled-components는 CSS와 컴포넌트를 결합하는 강력한 도구
✔ props를 활용하면 조건부 및 동적 스타일링도 손쉽게 구현
✔ ThemeProvider로 확장성 높은 디자인 시스템 구축 가능
✔ 전통적인 방식과 비교해 유지보수와 재사용성에서 큰 강점

반응형
반응형

React에서 CSS 적용하기 : 3가지 방법과 활용법

여러분, 리액트 개발할 때 CSS 스타일링 어떻게 하세요?
막막하거나 헷갈릴 때 많지 않나요?

안녕하세요, 여러분!

오늘은 리액트(React)로 웹앱을 만들면서 가장 자주 부딪히는 문제 중 하나,

바로 "어떻게 CSS를 적용할까?"에 대한 이야기를 해보려고 해요.

 

저도 처음 리액트를 접했을 때는 기존처럼 CSS 파일만 쓰면 되는 줄 알았는데, 시간이 갈수록 방법이 많아지더라구요.

그래서 오히려 뭐가 좋고 나쁜지 더 헷갈렸던 기억이 납니다. 😵

 

이번 글에서는 React에서 가장 널리 사용되는 3가지 CSS 적용 방식을 정리하고,

각각 어떤 상황에서 쓰면 좋은지 실전 코드 예제와 함께 소개해드릴게요.

마지막에는 장단점 비교표도 있으니 끝까지 봐주세요!

1. 일반 CSS 파일 사용하기

React에서 가장 기본적이고 직관적인 방식이죠.

전통적인 CSS 파일을 작성해서, 해당 파일을 컴포넌트에서 import해서 사용하는 방식입니다.

만약 기존 HTML/CSS로 작업해본 경험이 있다면 이 방식이 가장 익숙할 거예요.

📘 사용 방법 예제

아래는 styles.css 파일과 App.js 컴포넌트에서 적용한 예제입니다.

/* styles.css */
.container {
  background-color: #f4f4f4;
  padding: 20px;
  border-radius: 10px;
}

.text {
  color: darkblue;
  font-size: 16px;
}
// App.js
import './styles.css';

function App() {
  return (
    <div className="container">
      <p className="text">Hello, React!</p>
    </div>
  );
}

export default App;

✅ 장점

  • 익숙하고 간단하다 – 기존 HTML+CSS 경험이 있다면 바로 적용 가능
  • 빠르게 스타일링 적용 가능해서 소규모 프로젝트에 적합

⚠️ 단점

  • 클래스명이 전역(Global)이라서 컴포넌트 간 이름 충돌 발생 가능성 있음
  • 규모가 커질수록 유지 관리가 어려워질 수 있음

💡 언제 사용하면 좋을까?

간단한 프로젝트나 초기 개발 프로토타입을 빠르게 만들 때 가장 효율적이에요.

기존 웹 페이지 구조를 React로 옮기는 작업에서도 유용하죠.

다만 팀 프로젝트나 규모가 커지는 경우엔 충돌 위험이 커질 수 있으니 조심하세요!

 

 

2. 인라인 스타일링 (Inline Style)

이번에는 인라인 스타일링입니다. HTML의 style 속성을 떠올리시면 되는데, React에서는 조금 다르게 JavaScript 객체 형태로 작성해야 해요. 특히 동적으로 스타일을 바꾸는 상황에서 자주 활용됩니다.

🧪 사용 방법 예제

import { useState } from 'react';

function App() {
  const [isActive, setIsActive] = useState(false);

  const style = {
    backgroundColor: isActive ? "lightcoral" : "lightblue",
    padding: "20px",
    borderRadius: "10px",
    color: isActive ? "white" : "darkblue",
    fontSize: "18px",
  };

  return (
    <div style={style}>
      <p>Hello, Dynamic React!</p>
      <button onClick={() => setIsActive(!isActive)}>Toggle Style</button>
    </div>
  );
}

export default App;

보이시죠?

상태값(isActive)에 따라 배경색이나 글자 색이 즉시 바뀌는 구조입니다.

이게 인라인 스타일링의 강점이에요.

✅ 장점

  • 조건부 스타일 적용이 매우 간편함
  • 컴포넌트에 스타일이 묶여 있어서 유지보수 쉬움

⚠️ 단점

  • 스타일 재사용이 어렵다 – 다른 컴포넌트에서 동일한 스타일 쓰려면 복붙해야 함
  • 코드가 지저분하고 복잡해질 수 있음 – 스타일이 JSX 안에 섞이기 때문에 가독성이 떨어질 수도 있음

💡 언제 사용하면 좋을까?

동적으로 상태가 바뀔 때마다 스타일을 조정해야 하는 경우, 인라인 스타일링은 최적의 선택이 될 수 있어요.

단순한 버튼 색상 변경이나 알림창처럼 UI 반응형 요소 구현 시 정말 유용하답니다.

 

 

3. CSS 모듈 (CSS Module)

이번엔 조금 더 고급스럽고 안전한 스타일링 방법인 CSS 모듈에 대해 알아볼게요.

CSS 파일을 컴포넌트 단위로 모듈화하여 클래스 이름 충돌을 원천 차단해 주는 방식입니다.

그래서 중대형 프로젝트에서 특히 많이 쓰이는 스타일링 방법이기도 해요.

🧩 사용 방법 예제

/* Button.module.css */
.button {
  background-color: #007bff;
  color: white;
  padding: 10px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

.button:hover {
  background-color: #0056b3;
}
// Button.js
import styles from './Button.module.css';

function Button() {
  return (
    <button className={styles.button}>Click Me</button>
  );
}

export default Button;

보시는 것처럼 className직접 문자열이 아닌 객체로 접근하는 게 포인트예요.

styles.button처럼요.

이 덕분에 컴포넌트마다 고유한 클래스명이 자동 생성돼서, 충돌 걱정 없이 안심하고 스타일링할 수 있습니다.

✅ 장점

  • 클래스 이름이 자동으로 유니크해짐 – 충돌 걱정 NO!
  • 유지보수 용이하고 모듈별로 스타일 관리 가능

⚠️ 단점

  • 초심자에겐 약간의 진입 장벽이 있을 수 있음 (모듈 시스템 이해 필요)
  • 모듈 경로 관리가 귀찮을 수 있음 – 파일 수 많아지면 번거로움

💡 언제 사용하면 좋을까?

프로젝트가 커지고, 컴포넌트 수가 많아질수록 CSS 모듈의 힘이 발휘됩니다.

클래스 네이밍 충돌이 잦아지고, 스타일 유지보수가 어려워질 때, CSS 모듈은 진짜 구세주처럼 느껴질 거예요.

팀 프로젝트에서는 사실상 필수입니다. 😉

 

 

4. 세 가지 방식 비교표

지금까지 소개한 일반 CSS 파일, 인라인 스타일링, CSS 모듈은 각각 고유한 특징이 있고, 용도에 따라 적절한 선택이 필요합니다. 한눈에 비교할 수 있도록 표로 정리해봤어요.

방식 장점 단점
일반 CSS 파일 📌 간단하고 익숙함
📌 빠르게 적용 가능
📌 클래스 네임 충돌 가능성 있음
📌 전역 스타일로 유지보수 어려움
인라인 스타일링 📌 동적 스타일 적용 용이
📌 컴포넌트 내부 스타일 관리 가능
📌 스타일 재사용 어려움
📌 코드 복잡성 증가
CSS 모듈 📌 클래스 충돌 방지
📌 유지 관리 용이
📌 처음에는 학습 필요
📌 모듈 파일 수 증가

TIP 💬

단점이 있다고 해서 피할 필요는 없어요!

각 방식은 상황에 따라 정말 강력한 무기가 될 수 있습니다.

중요한 건 어떤 방식이 현재 프로젝트 상황과 개발 스타일에 가장 잘 맞느냐예요.

 

예를 들어,

간단한 개인 포트폴리오 사이트에는 일반 CSS 파일만으로도 충분할 수 있고, 상태 기반으로 UI가 자주 바뀌는 대화형 페이지라면 인라인 스타일이 딱이에요.

규모가 큰 협업 프로젝트라면 CSS 모듈은 거의 필수 수준이죠.

 

 

5. 상황별 추천 활용법 💡

세 가지 스타일링 방식 모두 장단점이 뚜렷하다 보니, 어떤 걸 써야 할지 고민이 될 수 있어요.

그래서 제가 직접 써보면서 얻은 실전 기준을 기준으로 상황별 추천 조합을 정리해봤어요.

🧠 이런 경우엔 이렇게 써보세요!

상황 추천 스타일링 비고
🧪 빠른 프로토타입 제작 일반 CSS 파일 쉽고 빠르게 적용 가능
🎨 동적인 UI 스타일 필요 인라인 스타일링 상태 변화에 따른 실시간 적용
🛠 컴포넌트 수 많은 대규모 프로젝트 CSS 모듈 클래스 충돌 방지, 유지보수 편리
👨‍👧 팀 단위 협업 CSS 모듈 + BEM 방식 병행 코드 일관성 확보
🧩 재사용 가능한 UI 컴포넌트 개발 CSS 모듈 스타일의 지역화에 적합

그리고 꼭 하나만 고집할 필요는 없어요!

혼합해서 사용하는 것도 좋은 전략입니다.

 

예를 들어

전역 테마는 일반 CSS 파일로, UI 컴포넌트는 CSS 모듈로, 버튼 hover 효과는 인라인 스타일로 처리하는 식으로요.

 

💬 한마디만 더!

실무에서는 정답보다 팀의 합의와 협업 스타일이 더 중요하더라구요.

각 방식의 특성과 상황을 이해하고, 유연하게 선택할 수 있다면 그게 진짜 ‘프로 개발자’ 아닐까요?

 

 

6. 마무리 🎁

React에서 스타일을 입히는 방법은 정말 다양합니다.

오늘 알아본 일반 CSS 파일, 인라인 스타일링, CSS 모듈은 그중에서도 가장 기본적이고 실무에서 자주 쓰이는 방식들이에요.

각 방식은 프로젝트의 성격, 팀 규모, 유지보수의 난이도 등에 따라 유불리가 분명하니, 이번 기회에 내 상황에 맞는 스타일링 전략을 세워보세요. 🧭

 

마지막 팁 💬

혼합해서 쓰는 것도 전략입니다!

특히 디자인 시스템을 갖춘 프로젝트라면, 공통 요소는 CSS 파일로, 개별 컴포넌트는 CSS 모듈로 관리하고, 일부 상호작용 요소는 인라인 스타일로 처리하면 정말 유용해요.

 

이제 CSS 때문에 머리 아프지 마세요.

React에서도 스타일링은 충분히 깔끔하고 체계적으로 관리할 수 있으니까요. 😊

반응형
반응형

React로 UI 만들기: 초보자를 위한 컴포넌트 설계 입문

여러분 혹시, "React는 어렵다"는 얘기 들어보셨나요? 🤔
그 말, 반은 맞고 반은 틀렸습니다.
이 글을 끝까지 보면 그 이유, 분명해질 거예요!


 

안녕하세요,  여러분 👋

오늘은 React로 UI를 만들기 위한 기초 개념부터 컴포넌트 구성, JSX 사용법, 그리고 직접 만들어보는 카드 컴포넌트 예제까지 아주 디테일하게 안내해 드릴게요.

제가 처음 React를 접했을 때 겪은 시행착오와 노하우도 함께 공유할 거니까, 끝까지 함께 해주세요! 😄

1. React UI란 무엇인가요? (기초 개념)

우선 React는 Facebook에서 만든 자바스크립트 기반의 UI 라이브러리예요.

HTML 파일을 자바스크립트로 조립하듯 만들어서, 더 빠르고, 더 직관적인 사용자 경험을 제공하는 데 초점이 맞춰져 있죠.

 

쉽게 말해, 웹사이트에 버튼 하나 추가하거나, 리스트를 동적으로 업데이트하는 기능을 만들고 싶다면 React만큼 강력한 툴은 드물어요.

📌 React UI의 핵심 개념

  • 컴포넌트(Component): UI를 구성하는 최소 단위로, 독립적이고 재사용 가능한 블록입니다.
  • Virtual DOM: 변경 사항을 빠르게 반영해주는 React만의 효율적인 방식입니다.
  • JSX: HTML과 유사한 문법을 JavaScript 코드 안에 직접 작성할 수 있게 해줍니다.

 

🧐 그럼 왜 React UI가 중요한 걸까요?

  1. 1. 빠르고 효율적인 개발: 반복되는 UI 요소들을 컴포넌트로 만들어놓고 필요할 때마다 재활용할 수 있어요.
  2. 2. 실시간 반응성: 데이터가 바뀌면 자동으로 UI도 변하게 만들 수 있어요.
  3. 3. 유지보수 용이: 컴포넌트 기반이라 한 부분만 수정해도 전체 앱에 영향을 줄 수 있어요.

 

🌱 처음 접하는 초보자에게도 React는 좋은 선택일까?

물론이죠!

React는 처음에는 약간 헷갈릴 수 있지만, 한 번 구조를 익히면 이후 개발이 훨씬 쉬워져요.

저도 예전엔 "이걸 내가 할 수 있을까?" 싶었지만, 컴포넌트 한 개 만들어보고 나니 자신감이 붙더라구요.

 

초보자에게 React는 단순한 UI 툴이 아니라 프론트엔드 개발의 사고방식을 바꿔주는 계기가 될 수 있어요.

 

다음 단계에서는 React UI 개발이 왜 이렇게 각광받고 있는지 더 구체적인 이유들을 정리해 드릴게요. 😊

 

2. UI 설계에 React가 좋은 이유 ✨

React가 UI 개발에서 주목받는 이유는 그 자체가 사용자 경험을 위한 도구이기 때문이에요.

예쁘기만 한 UI보다, 빠르고 직관적인 상호작용이 가능한 UI를 만드는 게 더 중요하잖아요?

바로 이 지점에서 React가 강점을 발휘합니다.

💡 React가 UI 개발에 최적화된 이유

  • 실시간 반응성 (Reactivity): 데이터가 바뀌면 자동으로 화면이 업데이트돼요.
  • 컴포넌트 단위 설계: UI 요소를 블록처럼 쌓고 조립해서 만들 수 있어요.
  • Virtual DOM: 불필요한 렌더링을 줄여서 성능을 높여줘요.

 

🧠 비교: 전통적인 UI 개발 vs React

항목 전통적인 방식 React 방식
코드 구조 HTML/CSS/JS 분리 컴포넌트로 통합
재사용성 낮음 매우 높음
상태관리 전역 변수/이벤트 위주 useState, Context 등 구조화
UI 업데이트 수동 DOM 조작 자동 반응형 렌더링

제가 초기에 Vanilla JS만으로 UI를 관리했을 때, 한 줄 수정하면 두 줄이 깨지고 다섯 줄을 다시 써야 했던 기억이 나요. 😂

그런데 React로 바꾸고 나서는 마치 블록 조립하듯 UI를 만들 수 있었어요.

그 정도로 개발 효율성이 확 올라갑니다!

🚀 요약: React로 UI를 만들면 이런 점이 좋아요

  • 초보자도 입문 가능! 이해하기 쉬운 컴포넌트 구조
  • 빠르고 부드러운 UX를 자동으로 구현 가능
  • 유지보수성 극대화: 기능 수정 시 전체 코드를 건드릴 필요 없음

 

이제 React가 단순히 “멋져 보이는 라이브러리”가 아니라 실제로 실무에서 왜 쓰이는지 이해가 되셨죠?

다음 챕터에서는 컴포넌트 구조의 비밀을 더 깊이 들여다볼게요. 🧩

 

3. 컴포넌트 구조와 장점 🔧

React의 핵심은 뭐니 뭐니 해도 컴포넌트(Component)입니다.

처음엔 낯설지만, 이 구조에 익숙해지면 복잡한 UI도 쉽게 관리할 수 있게 되죠.

마치 레고 블록을 조립하듯 화면을 만들어간다고 보면 돼요. 🎮

🧩 컴포넌트란 무엇인가요?

컴포넌트는 말 그대로 UI를 구성하는 독립적인 조각입니다.

이 조각들은 각자 자신만의 상태와 스타일, 동작을 가지고 있어서 수정·재사용이 쉬워요.

  • 컴포넌트는 기본적으로 함수(function)나 클래스(class)로 만들어집니다.
  • 보통은 함수형 컴포넌트 + 훅(Hooks)을 더 많이 사용합니다.

 

📌 컴포넌트 구조 예시

function Header() {
  return (
    <header>
      <h1>My Blog</h1>
    </header>
  );
}

 

위 예제처럼 Header라는 컴포넌트를 하나 만든 다음,

메인 화면에서 <Header />처럼 태그로 불러와 쓰면 됩니다.

진짜 HTML 태그처럼 쓸 수 있다는 게 핵심이에요!

🧠 컴포넌트 기반 구조의 장점

장점 설명
재사용성 같은 UI를 여러 군데에서 반복해서 사용할 수 있어요.
유지보수 용이 한 군데만 수정해도 전체 동작에 영향을 줄 수 있어요.
테스트 편리성 각 컴포넌트를 독립적으로 테스트할 수 있어요.

React로 처음 프로젝트를 시작할 때는 무조건 "작게 쪼개기"부터 연습해보세요.

버튼, 카드, 폼 등 각 UI 요소를 개별 컴포넌트로 만들고, 필요한 곳에서 조합하는 게 핵심이에요.

 

처음엔 비효율적으로 느껴질 수 있어도, 프로젝트가 커질수록 "이래서 컴포넌트 구조가 필요했구나" 하고 깨닫게 될 거예요.

 

자, 이제 다음 챕터에서는 이 컴포넌트를 만드는 도구인 JSX에 대해 알아볼 차례입니다.

조금 헷갈릴 수 있지만, 설명은 진짜 쉽게 해드릴게요! 😎

 

4. JSX 제대로 쓰는 법 🧠

JSX는 JavaScript + XML의 줄임말이에요.

React에서 UI를 설계할 때 가장 많이 쓰는 문법이고, 익숙해지면 마치 HTML을 쓰듯이 JavaScript 안에서 UI를 그릴 수 있습니다. 🤓

📘 JSX의 기본 문법

JSX는 XML처럼 생긴 문법을 사용하지만, 사실은 전부 JavaScript 코드로 변환돼요.

그래서 HTML처럼 보이지만 완전히 같지는 않아요!

const element = <h1>Hello, JSX!</h1>;

 

이렇게 <h1> 태그를 마치 HTML처럼 직접 쓸 수 있다는 게 바로 JSX의 핵심이에요.

⚠️ JSX와 HTML의 차이점

  • class → className: JSX에서는 class 대신 className을 써야 해요.
  • 닫는 태그 필수: <br />, <img /> 처럼 반드시 태그를 닫아야 합니다.
// HTML
<div class="box">Hello</div>

// JSX
<div className="box">Hello</div>

🔄 JSX에서 JavaScript 사용하기

JSX 내부에서는 { } 중괄호를 이용해 동적으로 데이터를 삽입할 수 있어요.

이게 진짜 React의 매력이죠!

const name = "React";

function Greeting() {
  return <h1>Hello, {name}!</h1>; 
}

// 결과: Hello, React!

🧠 JSX를 쓰면 뭐가 좋을까?

  1. 1. 직관적이고 읽기 쉬움: 마치 HTML처럼 보여서 비개발자도 이해 가능!
  2. 2. 동적 UI 구현에 탁월: 변수/함수/조건 등을 자유롭게 삽입
  3. 3. React 기능과 완벽 호환: Hooks, Props, State 등과 함께 자연스럽게 사용 가능

JSX에 익숙해지면 복잡한 동적 UI도 코드 몇 줄로 해결할 수 있어요.

자, 이제 실전으로 들어가 봅시다!

다음 단계에서는 컴포넌트를 어떻게 설계하고 나누는지 구체적인 패턴과 함께 살펴볼게요. 🔍

 

 

5. 컴포넌트 설계 원칙과 실제 예제 🎯

이제 컴포넌트를 어떻게 나누고 설계해야 효율적일까?에 대해 알아볼 시간입니다.

사실 이 부분에서 React의 진짜 힘이 드러나거든요! 🙌

🎨 컴포넌트를 잘 나누는 3가지 기준

  1. ① 단일 책임 원칙(SRP) — 하나의 컴포넌트는 하나의 역할만!
  2. ② 재사용 가능성 — 중복되는 구조는 컴포넌트로 빼세요.
  3. ③ 계층 구조 — 부모 컴포넌트와 자식 컴포넌트를 구분해서 설계하세요.

즉, "이 UI 블록을 다른 곳에서도 쓸 수 있을까?"

     "이 기능은 따로 테스트 가능할까?"

이런 기준으로 쪼개기 연습을 하는 게 중요합니다.

👨‍💻 실제 예제: 사용자 프로필 컴포넌트

다음은 UserProfile이라는 상위 컴포넌트를 기준으로 3개로 나눠본 예제입니다.

function UserInfo({ name, email }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  );
}

function UserActions() {
  return <button>Send Message</button>;
}

function UserProfile({ user }) {
  return (
    <div>
      <UserInfo name={user.name} email={user.email} />
      <UserActions />
    </div>
  );
}
  • 🧠 UserInfo: 사용자 이름과 이메일만 담당
  • 📨 UserActions: 버튼 액션 담당 (확장 가능)
  • 👤 UserProfile: 위 두 컴포넌트를 조합한 상위 컴포넌트

✅ 실무 팁: 이런 컴포넌트 쪼개기가 도움이 돼요

  • 버튼, 카드, 텍스트 필드 같은 UI 요소는 전부 재사용 가능한 컴포넌트로 분리
  • 로직과 뷰를 분리하면 유지보수가 쉬워지고, 테스트 코드 작성도 편해짐

React에서 컴포넌트는 UI의 최소 단위예요.

컴포넌트를 나눌 줄 알면 어느 순간부터 앱 전체가 블록처럼 느껴지기 시작할 거예요.

그게 바로 React의 묘미죠! 😄

 

이제 마지막! 다음 STEP에서는 이 모든 개념을 담은 실제 컴포넌트를 만들어보며 마무리할게요. ✨

 

 

6. 카드 컴포넌트 만들기 실습 💻

지금까지 배운 JSX, 컴포넌트 구조, 설계 원칙을 바탕으로 실전 예제를 만들어볼 시간이에요.

초보자에게 가장 추천하는 예제는 카드 컴포넌트입니다.

간단하면서도 핵심 개념이 모두 들어가 있거든요. 🎴

💡 목표: 두 개의 카드 컴포넌트를 렌더링하기

/* eslint-disable react/prop-types */

function App() {
  return (
    <div>
      <Card title="React Basics" description="Learn the basics of React." />
      <Card title="JSX Guide" description="Understand how JSX works." />
    </div>
  );
}

function Card({ title, description }) {
  return (
    <div style={{ border: "1px solid #ccc", padding: "16px", borderRadius: "8px", marginBottom: "12px" }}>
      <h2>{title}</h2>
      <p>{description}</p>
    </div>
  );
}

export default App;

📦 이 코드에서 확인할 수 있는 개념

  • props 사용: title, description이라는 데이터를 부모에서 자식 컴포넌트로 전달
  • 스타일링: 인라인 CSS로 간단한 박스 형태의 카드 구현
  • 컴포넌트 재사용: Card 컴포넌트를 여러 번 불러서 다른 데이터를 출력

🔐 propTypes를 사용해서 더 안전하게 만들기

import PropTypes from 'prop-types';

function Card({ title, description }) {
  return (
    <div style={{ border: "1px solid #ccc", padding: "16px", borderRadius: "8px" }}>
      <h2>{title}</h2>
      <p>{description}</p>
    </div>
  );
}

Card.propTypes = {
  title: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired,
};

 

propTypes는 타입 오류를 미리 막아줘요. 개발하면서 실수를 줄일 수 있어서 실무에선 거의 필수랍니다. 😎

카드 컴포넌트 예시 출력 결과

▲ 카드 컴포넌트 출력 결과 (React)

 

이제 여러분도 직접 나만의 React 컴포넌트를 만들 수 있어요! 🎉

이번 실습을 시작으로 프로젝트에서 복잡한 UI를 다룰 수 있는 기반이 생겼다고 보셔도 됩니다.

📌 마무리 요약

  • 컴포넌트는 작고 독립적으로 쪼개자!
  • JSX는 HTML처럼 보이지만 JavaScript 그 자체!
  • props와 propTypes로 데이터 전달과 안전성 확보!

이제 진짜 기초는 다 끝났어요!

이 글을 바탕으로 작은 프로젝트부터 시작해 보세요. 🏃‍♂️

📌 마무리

여기까지 따라오신 여러분, 정말 고생 많으셨어요! 🎉

이번 글에서는 React의 기본 개념부터 JSX 문법, 컴포넌트 설계, 카드 UI 실습까지 한 번에 쭉 훑어봤어요.

처음엔 어렵게 느껴질 수 있지만, 지금 당장 모든 걸 완벽히 이해하지 않아도 괜찮아요.

중요한 건 작은 단위의 컴포넌트를 만들고, 직접 사용해보는 경험을 꾸준히 쌓는 거예요.

경험이 곧 내 것이 되니까요.

앞으로 더 다양한 컴포넌트 예제, 실무 적용 팁, 디자인 시스템 연동까지 다룰 예정이니,

블로그 구독다음 글 알림 설정해 주세요!

 

🙌 React를 여러분만의 무기로 만들어 드릴게요. 💪

반응형
반응형

React의 실행 과정 자세히 살펴보기

여러분 혹시 React 앱이 '딱 실행되는 순간'에 무슨 일이 일어나는지 궁금해본 적 있으세요?
우리가 매일 쓰는 이 프레임워크가 브라우저에서 어떻게 돌아가는지 안다면,
디버깅도 훨씬 쉬워지고 성능 최적화도 감이 잡히기 시작해요!

안녕하세요!

오늘은 React 앱의 실행 흐름에 대해 차근차근 뜯어보는 시간을 가져보려 해요.

React를 처음 접했을 때 가장 헷갈리는 부분 중 하나가 바로 "대체 어떤 순서로 실행되고 렌더링되는 거지?"라는 거잖아요.

그래서 준비했습니다. index.html부터 컴포넌트 렌더링, 가상 DOM과 diffing 알고리즘까지!

이미지를 곁들여 시각적으로도 쉽게 이해할 수 있도록 구성했으니까, React를 막 배우는 분들이라면 꼭! 끝까지 읽어주세요 😊

 

 

 

1. React 앱의 초기 로딩 🚀

React 앱은 단순한 HTML 문서처럼 보이지만, 사실 정교한 번들링 시스템렌더링 흐름을 포함하고 있어요. 앱을 브라우저에서 처음 실행할 때는 다음과 같은 단계가 순차적으로 이뤄집니다.

① HTML 파일 로드 📄

  • React 프로젝트는 index.html이 기본 진입점입니다.
  • 해당 HTML 파일은 매우 간단하지만 React 앱의 기반 DOM 요소를 담고 있어요.
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="/static/js/bundle.js"></script>
  </body>
</html>

이 중에서 <div id="root">가 가장 중요해요! React가 여기 안에 모든 UI를 렌더링하거든요.

② JavaScript 번들 로드 📦

이제 HTML을 다 불러왔으면, 본격적으로 JavaScript 번들 파일이 등장합니다. React 앱에서 작성한 모든 JS 코드들은 Webpack이나 Vite 같은 번들러를 통해 bundle.js로 합쳐져요.

  • 이 파일은 모든 React 컴포넌트, 상태 관리 코드, 라우팅 로직 등을 포함하고 있어요.
  • 브라우저가 이 JS 번들을 실행하면서 React 앱이 동작을 시작하죠.

🔎 정리: 초기 로딩 순서

단계 설명
1 index.html 로드 (root div 포함)
2 bundle.js 로딩 (JS 번들 실행)
3 React 앱 구동 시작

이 모든 일이 단 0.몇 초 안에 일어난다는 사실, 진짜 놀랍지 않나요? 😮

이제 다음으로 넘어가서 실제 React 컴포넌트가 DOM에 어떻게 렌더링되는지 확인해볼게요!

 

2. ReactDOM을 사용한 렌더링 🖥️

HTML이 모두 로드되고, JavaScript 번들이 실행되면 드디어 ReactDOM이 등장해요.

이 녀석이 하는 일은, 우리가 만든 React 컴포넌트를 브라우저의 DOM에 실제로 "마운트"하는 것입니다.

즉, 눈에 보이게 만들어주는 거죠!

① createRoot 사용법 (React 18 기준)

예전에는 ReactDOM.render를 썼지만, 이제는 React 18부터는 createRoot가 표준이 되었어요.

이건 동시성 기능(concurrent rendering)을 제대로 활용하기 위해 도입된 변화랍니다.

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

 

이 코드에서 createRoot는 브라우저 DOM에서 id가 root인 요소를 찾아 React 앱을 거기에 렌더링하겠다고 선언하는 거예요.

② App 컴포넌트는 왜 항상 위에 있을까?

  • App 컴포넌트는 React 앱의 진입점이자 최상위 컴포넌트입니다.
  • 이 안에서 다른 모든 컴포넌트들이 트리 구조로 하위에 배치되어요.

이 구조는 마치

HTML의 <body> 안에 섹션들이 있는 것

처럼 생각하면 돼요.

모든 페이지와 기능은 결국 이 App 컴포넌트 안에서 시작됩니다.

📌 실전 포인트 요약

항목 설명
createRoot React 18의 렌더링 시작점. 동시성 지원
App 컴포넌트 모든 컴포넌트 트리의 최상단 위치
root div 실제 HTML에서 React가 렌더링되는 공간

여기까지 오면 이제 화면에 React가 "짠!" 하고 나타나는 거죠.

다음 단계에서는 App 안에서 어떻게 컴포넌트들이 그려지는지 더 깊이 들어가 볼게요 🎨

 

3. 컴포넌트 구조와 JSX 변환 🎨

React의 진짜 매력은 바로 컴포넌트 기반 아키텍처에 있어요.

컴포넌트를 쌓고 연결하고 조립해서 하나의 앱을 완성하는 방식은 정말 직관적이고, 마치 레고 블록을 조립하는 것 같죠.

① 함수형 컴포넌트의 기본 구조

function App() {
  return (
    <div>
      <h1>Hello, React!</h1>
      <MyComponent />
    </div>
  );
}

 

이건 React 앱에서 가장 기본적인 구조예요.

<MyComponent />처럼 다른 컴포넌트를 끼워넣는 것도 엄청 간단하죠?

② JSX: JavaScript + XML?

React에서 사용하는 문법인 JSX는 말 그대로 JavaScript 안에서 HTML을 작성하는 느낌이에요.

근데 사실 이건

 

브라우저가 직접 해석할 수 없어요

 

  • Babel이 JSX를 JavaScript 코드로 변환해줘요.
  • JSX는 결국 React.createElement() 호출로 바뀌어요.

🧪 JSX 변환 예시

JSX 코드 JS 코드 (변환 결과)
<h1>Hello</h1> React.createElement('h1', null, 'Hello')
<div className="box"></div> React.createElement('div', { className: 'box' })

즉, JSX는 편하게 작성하기 위한 껍데기고, 진짜 중요한 건 React의 내부 함수들이라는 거예요.

🧩 정리: React 컴포넌트 핵심 요약

  1. React는 컴포넌트 단위로 UI를 구성
  2. JSX를 이용해 컴포넌트 작성
  3. JSX는 Babel을 통해 JS로 변환

다음 챕터에서는, 이 JSX로 만들어진 컴포넌트가 어떻게 가상 DOM을 만들고, 최종 화면으로 이어지는지 볼 거예요.

진짜 React의 마법이 시작되는 순간이죠! 🌳✨

 

4. 가상 DOM과 리렌더링 과정 🌳

React의 핵심을 단 하나만 꼽으라면, 단연 Virtual DOM(가상 DOM)이에요.

그냥 DOM을 쓰지 왜 굳이 가상을 만들었을까요?

그 이유는 바로... 성능입니다.

① Virtual DOM이란?

  • 메모리 상에 존재하는 DOM의 복사본이에요.
  • 실제 DOM을 직접 건드리지 않고, 변경 내용을 먼저 Virtual DOM에 적용해봐요.

왜 이렇게 하냐구요?

DOM 조작은 무겁고 느리니까요

React는 효율적으로 비교하고 최소한의 변경만 실제 DOM에 반영하려는 거예요.

② 리렌더링 흐름 정리 🔄

  1. 컴포넌트 상태(state)나 props가 변경됨
  2. 변경된 상태를 기반으로 새 Virtual DOM을 생성
  3. 이전 Virtual DOM과 새 Virtual DOM을 비교 (Diffing)
  4. 변경이 필요한 최소한의 실제 DOM 조작만 수행

📊 성능 비교 예시

방식 DOM 조작 범위 성능
기존 방식 전체 DOM 새로 그리기 느림
React 방식 변경된 부분만 반영 빠름

🔍 Diffing 알고리즘의 핵심

React는 O(n) 복잡도의 효율적인 알고리즘으로 이전 가상 DOM과 새 가상 DOM을 비교해요.

동일한 컴포넌트는 key를 기준으로 비교하고, 재사용 가능한 건 살리고 아닌 건 새로 생성하죠.

 

이 과정을 통해 React는 실제 DOM 변경을 최소화하면서도 UI를 항상 최신 상태로 유지해주는 거예요.

정말 효율적이죠?

다음은 상태(state)와 props가 이 흐름에 어떻게 영향을 주는지 알아봅시다 ⚙️

 

5. 상태(State)와 Props 흐름 ⚙️

React를 제대로 이해하려면 반드시 알아야 할 두 가지가 있어요.

바로 stateprops입니다.

이 둘이 어떻게 흐르고, 변경되며, UI를 업데이트시키는지 알면 React는 거의 마스터했다고 봐도 무방해요!

① Props: 외부로부터 받는 데이터

  • 부모 컴포넌트가 자식 컴포넌트에 전달하는 값이에요.
  • 읽기 전용이며 컴포넌트 내부에서 수정할 수 없어요.
function Welcome(props) {
  return <h1>안녕하세요, {props.name}님!</h1>;
}

② State: 내부에서 바뀌는 값

  • 컴포넌트 내부에서 생성되고 관리되는 데이터입니다.
  • useState 훅을 사용해서 선언하고 갱신해요.
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>현재 카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

📌 Props vs State 요약 비교

구분 Props State
역할 부모 → 자식 데이터 전달 컴포넌트 내부 데이터 관리
변경 가능 여부 읽기 전용 변경 가능 (setState 또는 set 함수)
리렌더링 변경 시 자식만 렌더링 변경 시 해당 컴포넌트 리렌더링

즉, props는 위에서 아래로 흐르는 값이고, state는 컴포넌트 내부에서 변화하는 값이에요.

이걸 이해하면 이제 사용자 입력이나 이벤트에 따라 어떻게 UI가 바뀌는지도 훨씬 잘 이해되실 거예요 😊

 

6. 이벤트 처리와 최종 업데이트 🔁

자, 이제 우리가 만든 React 앱에 사용자가 클릭하거나, 입력하거나, 마우스를 올리는 등의 이벤트가 발생할 때 무슨 일이 벌어지는지를 알아볼 차례예요.

이건 React 앱이 ‘살아있다’는 걸 보여주는 아주 중요한 부분이에요!

① 이벤트 바인딩 방식

HTML처럼 onclick 이런 거 안 써요!

React에서는 카멜 표기법으로 이벤트를 정의하고, 함수도 함께 넘겨야 해요.

function ButtonClicker() {
  const handleClick = () => {
    alert('버튼이 클릭되었습니다!');
  };

  return (
    <button onClick={handleClick}>클릭해보세요</button>
  );
}

② 상태(state) 변화 → 리렌더링

사용자가 이벤트를 일으키면, 대부분은 내부 상태(state)에 변화가 생겨요.

그러면 React는 전체 컴포넌트를 다시 렌더링하는 게 아니라, 변경된 부분만 골라서 가상 DOM을 통해 업데이트해요.

📌 실전 예제 - 카운터 버튼

function Counter() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>현재 숫자: {count}</p>
      <button onClick={() => setCount(count + 1)}>+ 증가</button>
    </div>
  );
}

 

여기서 버튼을 누를 때마다 count 값이 증가하고, 컴포넌트가 자동으로 다시 그려지는 거예요.

이게 React의 핵심 흐름이죠.

🔁 이벤트 → 상태 변화 → UI 반영 요약

  1. 사용자가 버튼 클릭 등 이벤트 발생
  2. 핸들러 함수 실행 → 상태 변화
  3. Virtual DOM이 새로운 UI 생성
  4. 변경된 부분만 DOM에 반영

📌 자주 쓰는 이벤트 목록

이벤트 종류 사용 예
onClick 버튼 클릭, 아이콘 클릭
onChange input, select 값 변경
onSubmit 폼 전송 시
onMouseEnter / Leave 호버 효과

이처럼 이벤트 처리 → 상태 변화 → 가상 DOM 생성 → DOM 업데이트까지!

이 모든 걸 React가 알아서 해준다는 거, 진짜 대단하지 않나요?

덕분에 우리는 비즈니스 로직에만 집중할 수 있죠! 🙌

 

🔚 React 실행 흐름, 이제 보이시나요?

지금까지 React 앱이 브라우저에서 실제로 어떻게 실행되는지, 그리고 그 속에서 어떤 로직이 일어나는지를 단계별로 살펴봤어요.

index.htmlbundle.jscreateRootJSX → 가상 DOM → 상태 변경 → 이벤트 → 리렌더링

이 전체 흐름이 머릿속에 하나의 선으로 연결되었다면,

여러분은 이제 진짜 React의 구조를 꿰뚫은 거예요! 🎉

 

처음엔 다소 복잡하게 느껴질 수도 있어요.

하지만 몇 번만 실습을 반복하면 자연스럽게 손이 기억하게 됩니다.

특히 상태와 props의 흐름, 그리고 가상 DOM의 작동 원리를 정확히 이해하면 훨씬 안정적인 코드와 성능 좋은 React 앱을 만들 수 있어요.

조금씩, 천천히, 꾸준히. React는 그렇게 여러분 편이 되어줄 거예요 😄

✅ 다음으로 하면 좋은 실습

  • React Developer Tools 확장 설치해서 Virtual DOM 직접 관찰해보기
  • 상태 변경에 따라 UI가 어떻게 변하는지 console.log로 추적해보기
  • 부모 → 자식 → 자식 → 다시 부모로 props/state 흐름 역추적해보기

 

반응형
반응형

2025년 Vite로 빠르게 React 프로젝트 만들기!
(JavaScript 버전)

“요즘 create-react-app 쓰면 손가락질 받는다? 😅”
빠르고 가볍게 시작하고 싶다면,
Vite로 React 프로젝트를 만들어보세요!

 

안녕하세요, 개발자 여러분! 혹시 아직도 create-react-app으로 새 프로젝트 시작하시나요?
그럼 오늘 이 글이 꽤 도움이 될지도 몰라요. 😊
2025년 현재, 더 이상 CRA는 주류가 아니에요.

개발자 커뮤니티에서도 빠르고 가벼운 도구로 Vite가 대세로 떠오르고 있습니다.
이 글에서는 초보자도 따라할 수 있도록, Vite로 React 프로젝트를 만들고 실행하는 전 과정을
이미지와 명령어 중심으로, 하나하나 쉽게 설명드릴게요.

1. Vite란? 왜 써야 할까? ⚡

여러분은 React 프로젝트를 만들 때 어떤 도구를 쓰시나요?
불과 몇 년 전만 해도 create-react-app(CRA)이 대세였죠. 하지만 요즘은 좀 다릅니다.
빠르고 가벼운 빌드 도구, 바로 Vite(비트)가 대세로 떠오르고 있어요!

📌 기존 CRA의 단점

  • 느린 초기 빌드 시간 — 개발 서버 실행하는 데 시간이 오래 걸려요.
  • 불필요한 파일 생성 — 쓰지도 않는 파일이 덕지덕지...
  • 유지보수 어려움 — 커스터마이징하려면 eject 해야 되는 복잡함...

🌟 그래서 등장한 Vite!

Vite는 Rollup 기반의 번들러로서, 빠른 개발 서버 실행과 즉각적인 반영을 제공합니다.
무려 HMR(Hot Module Replacement)도 기본 탑재되어 있고요.

  • ⚡ 엄청나게 빠른 실행 속도 — CRA랑 비교 불가!
  • 🔄 HMR 지원 — 수정한 파일이 바로 반영!
  • 🧼 미니멀한 템플릿 — 불필요한 설정 없이 바로 사용 가능!
기능 create-react-app Vite
개발 서버 실행 속도 느림 매우 빠름 ⚡
기본 프로젝트 크기 무거움 가벼움
파일 구조 복잡 심플 & 직관적

 

이쯤 되면 "그래서 어떻게 쓰는 건데?"라는 궁금증이 생기시겠죠?
이제 다음 섹션에서 바로 Node.js 설치부터 확인해볼게요!

 

2. Node.js 설치 및 확인하기 🧱

Vite를 사용하려면 Node.js가 필수예요. 왜냐고요?
Vite는 Node 환경에서 동작하는 도구이기 때문에 npm과 함께 동작하거든요.
그래서 먼저 우리 컴퓨터에 Node가 깔려 있는지부터 확인해봐야 합니다.

✅ 설치 여부 확인 방법

터미널이나 명령 프롬프트(cmd)를 열고 아래 명령어를 입력해보세요.

node -v

 

아래처럼 버전이 뜨면 성공! 🎉

예를 들어 이렇게 나올 거예요:

v18.17.1

❌ 설치 안 되어 있으면?

그럴 땐 아래 공식 사이트에서 LTS 버전을 받아 설치하면 됩니다.

👉 https://nodejs.org/ko

Node.js 공식 홈페이지 썸네일

참고로,

설치 시 윈도우 사용자라면 Node.js + npm이 함께 설치되기 때문에 따로 설정할 필요는 없어요.
정말 간단하죠?

📌 npm도 같이 확인해보세요!

npm -v

 

Node.js 설치 실습 영상

https://youtu.be/WmcLI60OnU0

 

 

이 명령어도 잘 작동한다면, 이제 다음 단계인 Vite로 프로젝트 생성하기로 넘어갈 준비 완료입니다! 😎

 

3. Vite로 React 프로젝트 생성하기 🛠️

자, 이제 본격적으로 Vite로 리액트 프로젝트를 만들어볼 시간입니다!
아래 단계별로 명령어를 따라가면 누구나 쉽게 첫 Vite 프로젝트를 만들 수 있어요.

① 프로젝트 생성 명령어

npm create vite@latest my-react-app

 

위 명령어를 입력하면 아래와 같이 프롬프트가 순차적으로 나옵니다.

  1. 프로젝트 이름 입력 — 기본값: my-react-app
  2. 프레임워크 선택React 선택
  3. Variant 선택JavaScript 선택 (TypeScript도 선택 가능)
Vite 프레임워크 선택 화면
JavaScript 템플릿 선택 화면

② 프로젝트 폴더로 이동 & 패키지 설치

cd my-react-app
npm install

 

이제 Vite가 기본 세팅해준 프로젝트 템플릿이 준비되었어요!
이 상태에서 바로 실행까지 할 수 있답니다.

 

Vite로 React 프로젝트 생성 실습 영상

https://youtu.be/cSApyMgNq1Q

 

💡 참고 꿀팁!

  • VSCode로 폴더 열기: code . 입력하면 바로 열려요!

여기까지 오셨으면 거의 70%는 끝났다고 보셔도 됩니다.
이제 남은 건 개발 서버 실행해서 직접 React 화면을 확인하는 것뿐!

 

4. 프로젝트 실행과 개발 서버 확인하기 🚀

이제 진짜 React 프로젝트가 작동하는지 확인해봐야죠!
Vite는 CRA보다 훨씬 빠르게 개발 서버를 실행할 수 있어요.

▶ 개발 서버 실행

npm run dev

 

명령어를 실행하면, 아래와 같이 개발 서버 주소가 출력될 거예요:

  Local: http://localhost:5173/

 

해당 주소를 브라우저에 붙여넣거나, 커맨드라인에서 Ctrl + 클릭으로 열어보세요.
기본 Vite + React 화면이 나온다면... 성공입니다! 🎉

 

💡 팁: 종료할 땐?

  • Ctrl + C 누르면 서버를 종료할 수 있어요!

지금까지 따라오셨다면, 이제 React + Vite 환경이 완벽하게 준비된 상태입니다. 👏
이제 코드도 살펴보고, 직접 수정해보면서 익숙해지면 됩니다.

 

5. 프로젝트 폴더 구조 이해하기 🗂️

이제 프로젝트가 실행됐으니, 내부 구조도 좀 살펴볼까요?
처음엔 폴더 안에 뭐가 뭔지 잘 모를 수 있지만, 핵심만 알면 금방 익숙해집니다!

📁 기본 디렉토리 구성

my-react-app/
├── public/          # 정적 파일 (favicon 등)
├── src/             # 실제 소스 코드 위치
│   ├── App.jsx      # 메인 React 컴포넌트
│   ├── main.jsx     # 진입 파일 (엔트리포인트)
│   ├── index.css    # 글로벌 스타일
├── .gitignore       # Git에서 무시할 파일 목록
├── package.json     # 프로젝트 메타 정보 및 의존성
├── vite.config.js   # Vite 설정 파일

 

여기서 가장 중요한 건 src/App.jsxmain.jsx입니다.
이 두 파일이 화면에 무엇을 어떻게 렌더링할지를 결정해요.

🧠 각 파일 간단 요약

파일/폴더 설명
public/ 정적 자산 저장 폴더 (HTML, 이미지 등)
src/App.jsx 메인 컴포넌트, 실제 화면 렌더링 담당
src/main.jsx ReactDOM을 이용해 App.jsx를 루트에 연결
vite.config.js Vite 설정 (경로 alias 등 커스터마이징 가능)
package.json 프로젝트 정보 및 의존성 목록

 

지금 구조만 잘 이해해도 앞으로 리액트 프로젝트 유지보수가 한결 쉬워질 거예요.
다음은 드디어 코드를 직접 수정해서 화면을 바꿔보는 시간입니다!

 

6. App.jsx 수정해서 기본 화면 바꾸기 🎨

자~ 이제 우리만의 메시지를 담아볼 시간이에요!
Vite가 생성해준 기본 화면을 내 입맛대로 살짝 바꿔보면,
"오~ 진짜 내 프로젝트 같네?" 싶은 뿌듯함이 생기거든요. 😆

📌 App.jsx 열어서 수정해보기

1. src/App.jsx 파일을 열어주세요.
2. 아래 코드처럼 기본 JSX 구조를 간단하게 바꿔볼게요.

function App() {
  return (
    <div style={{ padding: '2rem', textAlign: 'center' }}>
      <h1>Hello, React with Vite! 🚀</h1>
      <p>처음 만든 나만의 리액트 앱이에요. 너무 신나요! 😍</p>
    </div>
  );
}

export default App;

 

저장하면… 놀라지 마세요. 😮

 

바로 화면에 반영됩니다!

🔥 HMR 기능 덕분이에요!

  • HMR(Hot Module Replacement)은 코드 저장 시 자동 새로고침 없이 반영!

이제부터는 내 마음대로 컴포넌트도 추가하고, CSS도 꾸며보면서 진짜 프로젝트처럼 키워나갈 수 있어요.
처음의 이 한 걸음이, 나중엔 큰 앱으로 성장할 수도 있겠죠?

 

🧩 React 프로젝트, 이제 시작입니다!

오늘은 Vite를 활용한 React 프로젝트 시작 방법을 처음부터 끝까지 따라가 봤습니다.
생각보다 간단했죠?

CRA보다 훨씬 빠르고 가볍기 때문에, 앞으로 새 프로젝트는 이걸로 시작하는 게 좋습니다. 😊

정리해 보면 다음과 같아요.

  • Node.js 설치 여부 먼저 확인하고
  • npm create vite@latest 명령어로 새 프로젝트 생성
  • npm run dev로 바로 실행하고 확인까지 완료! 🔥

지금까지 잘 따라오셨다면, 앞으로 어떤 프로젝트든 가볍게 시작할 수 있을 거예요. 💪
다음 글에서는 React 컴포넌트를 좀 더 깊이 파보는 실전 예제를 다룰 예정이니 기대해주세요!

반응형

+ Recent posts