Node.js/React

[React] 리액트 컴포넌트란? 함수로 만드는 UI 조각

댕주 2025. 5. 5. 00:18

리액트는 UI를 컴포넌트 단위로 구성한다.

컴포넌트는 쉽게 말해 "화면을 구성하는 작은 조각"이다. 버튼 하나, 헤더 하나, 목록 하나도 모두 컴포넌트다.


✅ 함수 컴포넌트란?

가장 일반적인 방식은 "함수(function)"을 이용해서 컴포넌트를 만드는 것이다.

예를 들어, 헤더 컴포넌트를 만든다면 다음과 같이 작성할 수 있다.

// 함수 선언식
function Header() {
    return <header>헤더 입니다</header>
}

// 화살표 선언식
const Header = () => {
    return <header>헤더 입니다</header>
};

 

함수 선언식, 화살표 선언식 모두 기능은 동일하기 때문에 익숙한 방식으로 사용하면 된다.

클래스를 이용해서 선언할 수 있지만 코드가 복잡해져서 함수 방식이 일반적으로 사용된다.


✅ 함수 컴포넌트의 return 문법 - 괄호와 태그

리액트 함수 컴포넌트는 JSX 를 return 으로 반환한다. 이때 작성 방식에 따라 괄호 사용법이 달라진다.

1. 한 줄일 경우 괄호 없어도 OK

const Hello = () => <h1>안녕하세요</h1>;
  • JSX가 한 줄이면 괄호 없이 바로 반환 가능하다.
  • 단, JSX 문법은 <태그>로 시작해야 한다.

2. 여러 줄이면 괄호로 감싸야 함

const Hello = () => (
    <div>
        <h1>안녕하세요</h1>
        <p>만나서 반가워요</p>
    </div>
);
  • 여러 줄 JSX를 반환할 때는 괄호로 감싸야 한다.
  • 이 괄호는 JavaScript 문법상의 우선순위 문제를 피하기 위한 것.

3. JSX는 반드시 하나의 태그로 감싸야 함

// 오류 발생
const Hello = () => (
    <h1>안녕하세요<h1>
    <p>만나서 반가워요</p>
);

// 올바른 예시
const Hello = () => (
    <div>
        <h1>안녕하세요</h1>
        </p>만나서 반가워요</p>
    </div>
)
<></> 같은 Fragment 문법으로도 감쌀 수 있음
이는 불필요한 DOM 요소를 만들지 않아서 자주 쓰인다

✅ 왜 JSX는 하나의 태그만 반환해야 할까?

JSX는 결국 React.createElement() 호출로 변환되는데, 하나의 컴포넌트는 단 하나의 요소만 반환해야 하기 때문이다.

여러 개의 요소를 반환하면 구조적으로 모호해져서 에러가 발생한다.

작성 형태 문법 설명
한 줄 JSX return <태그 /> 괄호 생략 가능
여러 줄 JSX return (...) 괄호로 감싸야 함
JSX 요소 여러 개 <div>...</div> or <>...</> 하나의 부모 요소로 감싸야 함

✅ 함수 컴포넌트에서 return을 생략할 수 있는 경우

🔹 한 줄인 경우 - return 생략 가능

const Hello = () => <h1>안녕하세요</h1>; // return 생략 가능

const Hello = () => {
  return <h1>안녕하세요</h1>;
};

🔸 여러 줄인 경우 

// 중괄호 {} 로 열면 return 필요
const Hello = () => {
  return (
    <div>
      <h1>안녕하세요</h1>
      <p>반가워요!</p>
    </div>
  );
};

// 괄호 () 안에 바로 JSX 넣으면 return 생략 가능
const Hello = () => (
  <div>
    <h1>안녕하세요</h1>
    <p>반가워요!</p>
  </div>
);

🚫 주의할 점

const Hello = () => {
  // 괄호만 쓰고 return 안 쓰면 undefined 반환됨!
  (
    <h1>안녕하세요</h1>
  );
};
작성 형태 return 필요 여부 예시
한 줄 JSX 생략 가능 const A = () => <h1>Hi</h1>;
여러 줄 JSX + 괄호 () 생략 가능 const A = () => ( <div>...</div> );
중괄호 {} 사용 필요 const A = () => { return <div>...</div>; };

✅ 컴포넌트 이름 규칙

컴포넌트의 이름은 반드시 대문자로 시작해야 한다.

만약 소문자로 시작하면, 리액트는 이를 그냥 HTML 태그로 인식해버린다.

const header = () => <header>...</header>; // 잘못된 예시

✅ 컴포넌트를 사용하는 방법

컴포넌트는 태그처럼 사용할 수 있다.

const App = () => {
	return (
    	<div>
            <Header />
        </div>
    )
}

 

여기서 App 은 부모 컴포넌트, Header 는 자식 컴포넌트다.


✅ 루트 컴포넌트란 ?

모든 React 앱은 하나의 컴포넌트에서 출발한다.

이 컴포넌트를 루트 컴포넌트라고 부르는데, 관례상 이름은 App 을 사용한다.

루트 컴포넌트는 main.jsx 에서 렌더링된다.

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

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
리액트 앱에서 화면에 나타나는 모든 요소는 App 안에 포함돼야 한다.
App이 바로 렌더링의 출발점(조상 컴포넌트) 이기 때문이다.

✅ 컴포넌트 파일 분리

src/
├── App.jsx
├── components/
│   └── Header.jsx
// App.jsx
import Header from './components/Header';

function App() {
  return (
    <div>
      <Header />
    </div>
  );
}
ES Modules 는 원칙상 import 시 확장자를 명시해야 하지만
Vite 같은 번들러가 생략을 가능하게 해줌
🔧 설정된 확장자 우선순위 리스트를 따라 해당 파일을 자동으로 찾아서 연결

 

'Node.js > React' 카테고리의 다른 글

[React] JSX로 UI 표현하기  (0) 2025.05.05
[React] React App 구동원리 알아보기  (0) 2025.05.04
[React] React App 생성하기  (0) 2025.05.04
[React] 리액트란 무엇인가?  (0) 2025.05.04
[React] Quick Start - 1  (0) 2025.02.18