본문으로 건너뛰기

안동민 개발노트

본문 시작

첫 번째 React 앱 만들기

Vite 프로젝트의 파일 구조를 살펴보고 App 컴포넌트의 JSX와 CSS를 수정해 첫 React 화면을 완성합니다.

이 장에서는 그 기본 틀 위에서 여러분만의 첫 번째 리액트 앱을 만들어 봅니다.

리액트 코드가 실제로 어떻게 웹 페이지에 나타나는지 직접 경험해 볼 것입니다.

우리는 주로 src 폴더 안의 App.jsx 파일을 수정하며 리액트 컴포넌트를 작성하게 될 것입니다.

아직 모든 코드를 이해하지 못해도 괜찮습니다.

지금은 이것을 수정하면 웹 페이지가 이렇게 바뀌는구나! 하고 직관적으로 느껴보는 것이 중요합니다.

앱 부트스트랩과 개발 피드백. 브라우저가 index.html의 #root를 만납니다. main.tsx가 createRoot(root)를 호출합니다. App의 JSX가 DOM에 커밋됩니다. 저장 시 Vite Fast Refresh가 변경을 반영합니다.

BOOTSTRAP SEQUENCE

앱 부트스트랩과 개발 피드백

index.html의 root에서 React 루트를 만들고 App을 렌더한 뒤, 저장한 모듈 변경을 Vite가 개발 화면에 반영합니다.

앱 부트스트랩과 Vite Fast Refresh브라우저의 root에서 main.tsx가 App을 렌더하고, 개발 중 Vite Fast Refresh 모듈 갱신이 main.tsx를 거쳐 App 재렌더와 DOM 변경 커밋으로 이어집니다.#root 전달App renderJSX 반환DOM commit모듈 갱신App 재렌더JSX 반환변경 commitindex.html#root DOMmain.tsxcreateRoot · renderApp.tsxJSX 화면ViteFast Refresh · dev
BOOTSTRAP SEQUENCE· 390px 모바일 읽기 순서
  1. index.html

    브라우저가 index.html에서 React가 연결될 #root DOM을 제공합니다.

  2. main.tsx

    main.tsx가 createRoot(root) 뒤 App 렌더를 요청합니다.

  3. App.tsx

    App.tsx가 JSX를 반환하면 React가 첫 화면을 DOM에 커밋합니다.

  4. Vite · Fast Refresh

    개발 중 저장한 모듈을 Vite가 갱신하고 App 재렌더와 변경 커밋으로 이어집니다.

화살표는 원인에서 다음 렌더 단계로 흐르며, 강조 테두리는 이 절의 핵심 결과를 나타냅니다.


프로젝트 구조 살펴보기

VS Code로 my-first-react-app 프로젝트를 열고 왼쪽 탐색기(Explorer)를 보면 다음과 같은 폴더 및 파일 구조를 확인할 수 있습니다.

vite.svg # 기본 템플릿에서 쓰는 정적 이미지
...
react.svg # 기본 템플릿에서 쓰는 React 로고
App.css # App 컴포넌트의 스타일 시트
App.jsx # 메인 App 컴포넌트
index.css # 전역 스타일 시트
main.jsx # 리액트 앱의 시작점. App 컴포넌트를 root에 렌더링
.gitignore # Git이 추적하지 않을 파일 및 폴더 지정
index.html # root DOM을 제공하는 HTML 진입 파일
package.json # 프로젝트의 메타데이터, 의존성, 스크립트 정보
README.md # 프로젝트에 대한 설명 문서
vite.config.js # Vite 설정 파일
...

이 중에서 우리가 주로 관심을 가질 파일은 index.html, src/main.jsx, 그리고 src/App.jsx입니다.

  • index.html: 이 파일은 여러분의 리액트 애플리케이션이 로드될 기본 HTML 페이지입니다. <div id="root"></div>라는 빈 태그를 찾아보세요. 리액트 애플리케이션은 이 id="root"를 가진 div 안에 렌더링됩니다.
  • src/main.jsx: 이 파일은 리액트 애플리케이션의 시작점입니다. 여기서 App.jsx에서 가져온 <App /> 컴포넌트를 index.htmlroot 요소에 연결합니다.
  • src/App.jsx: 이 파일은 현재 웹 페이지에 보이는 내용을 담고 있는 메인 컴포넌트입니다. 우리는 주로 이 파일을 수정하면서 첫 번째 리액트 앱을 만들어 볼 것입니다.

App.jsx 수정하여 내용 변경하기

이제 VS Code에서 src/App.jsx 파일을 열어보세요.

기본 템플릿에는 Vite와 React 로고, 카운터 예제, HMR 안내 문구가 들어 있습니다.

처음에는 이 예제 코드를 단순한 화면으로 바꾸며 컴포넌트 함수가 반환한 JSX가 브라우저 화면이 된다는 점을 확인하면 됩니다.

이제 이 내용을 우리가 원하는 간단한 문구로 변경해 보겠습니다.

기존 내용 삭제 및 새 내용 추가 기본 예제에서 로고와 카운터 관련 import를 지우고, 다음과 같이 간단한 <h1> 태그와 <p> 태그를 반환해 보세요.

src/App.jsx
import './App.css';

function App() {
  return (
    <div className="App">
      {/* 여기에 새로운 내용을 작성합니다 */}
      <h1>나 혼자 React!</h1>
      <p>첫 번째 React 앱을 만들고 있습니다.</p>
      <p>정말 재미있네요!</p>
    </div>
  );
}

export default App;

파일 저장: 코드를 수정한 후 Ctrl+S (macOS: Cmd+S)를 눌러 파일을 저장합니다.

결과 확인: 개발 서버(npm run dev로 실행했던)가 여전히 실행 중이라면, 웹 브라우저(http://localhost:5173)를 새로고침하지 않아도 자동으로 변경된 내용이 화면에 나타나는 것을 확인할 수 있을 것입니다!

화면에 나 혼자 React!, 첫 번째 React 앱을 만들고 있습니다., 정말 재미있네요!라는 문구가 보인다면 성공입니다!


JSX에 대하여 잠시 알아보기

App.jsx 파일에서 return 문 안에 작성했던 <div className="App"> ... </div>와 같은 코드들을 보셨을 것입니다.

이것은 HTML처럼 생겼지만 사실은 JSX(JavaScript XML)라고 부르는 리액트만의 특별한 문법입니다.

JSX는 자바스크립트 안에 HTML(XML)과 유사한 문법을 사용하여 UI를 기술할 수 있도록 해줍니다.

언뜻 보면 HTML과 매우 유사하지만, 다음과 같은 몇 가지 중요한 차이점이 있습니다.

  • HTML 속성 이름: HTML에서 class라고 쓰는 속성은 JSX에서는 className으로 작성해야 합니다. forhtmlFor로 작성해야 합니다. 이는 classfor가 자바스크립트의 예약어이기 때문입니다.

  • 단일 루트 요소: 컴포넌트는 항상 하나의 최상위(Root) 요소를 반환해야 합니다. 예를 들어, 여러 태그를 나란히 반환하고 싶다면 하나의 <div><> (프래그먼트)로 감싸야 합니다.

    // ⭕ 올바른 JSX (하나의 div로 감싸져 있음)
    function MyComponent() {
      return (
        <div>
          <h1>제목</h1>
          <p>내용</p>
        </div>
      );
    }
    // ❌ 잘못된 JSX (두 개의 최상위 요소)
    // function MyComponent() {
    //   return (
    //     <h1>제목</h1>
    //     <p>내용</p>
    //   );
    // }

    <div>로 감싸는 것이 번거롭거나 불필요한 DOM 노드를 생성하고 싶지 않을 때는 <></>와 같은 빈 태그를 사용할 수 있는데, 이를 프래그먼트(Fragment)라고 부릅니다.

    // ⭕ 올바른 JSX (프래그먼트 사용)
    function MyComponent() {
      return (
        <>
          <h1>제목</h1>
          <p>내용</p>
        </>
      );
    }
  • 자바스크립트 표현식 삽입: JSX 내부에서 중괄호 {}를 사용하면 자바스크립트 표현식을 삽입할 수 있습니다. 예를 들어, 변수의 값이나 함수의 결과 등을 UI에 바로 렌더링할 수 있습니다.

    function Welcome() {
      const name = '독자 여러분';
      return (
        <h1>안녕하세요, {name}!</h1>
      );
    }

    JSX는 자바스크립트 안에서 UI 구조를 선언할 수 있게 해 줍니다.

    이후 예제에서는 JSX로 리액트 컴포넌트를 작성합니다.


스타일 적용하기

현재 여러분의 웹 페이지는 글씨가 작고 정렬이 되어있지 않아 보기에 좋지 않을 수 있습니다.

리액트 컴포넌트에 스타일을 적용하는 방법은 여러 가지가 있지만, 여기서는 Vite 기본 프로젝트에서 바로 사용할 수 있는 일반 CSS 파일인 App.css를 수정해 보겠습니다.

App.css 파일 수정: VS Code에서 src/App.css 파일을 열어 기존의 모든 내용을 삭제하고 다음과 같이 간단한 스타일을 추가해 보세요.

src/App.css
.App {
  text-align: center; /* 텍스트를 가운데 정렬 */
  background-color: #f0f0f0; /* 배경색 변경 */
  min-height: 100vh; /* 최소 높이를 뷰포트 높이로 설정 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin); /* 폰트 크기 조정 */
  color: #333; /* 텍스트 색상 변경 */
}

h1 {
  color: #007bff; /* 제목 색상 파란색 */
  margin-bottom: 20px;
}

p {
  color: #555; /* 단락 텍스트 색상 회색 */
  line-height: 1.5;
}

파일 저장: App.css 파일을 저장합니다.

결과 확인: 웹 브라우저를 확인하면 여러분이 추가한 스타일이 적용되어 텍스트가 가운데 정렬되고, 배경색과 폰트 색상이 변경된 것을 볼 수 있을 것입니다.

App.jsx 파일에서 import './App.css'; 라는 코드를 통해 CSS 파일을 불러왔기 때문에, 해당 스타일이 App 컴포넌트 화면에 적용됩니다.

리액트는 이처럼 자바스크립트 코드 내에서 CSS 파일을 불러와 화면 구조와 스타일의 연결을 한 곳에서 추적하기 쉽게 만듭니다.

첫 React 앱에서는 프로젝트 구조를 통째로 외우기보다 진입 파일, App 컴포넌트, 스타일, 브라우저 화면이 이어지는 경로를 확인합니다.

이 연결이 보이면 다음 장부터는 JSX 안에서 데이터를 표현하고 이벤트로 상태를 바꾸는 흐름을 훨씬 자연스럽게 따라갈 수 있습니다.