
컴포넌트란 리액트의 핵심 빌딩 블록 중 하나로, UI 요소를 표현하는 최소한의 단위이며 화면의 특정 부분이 어떻게 생길지 정하는 선언체입니다.
리액트의 컴포넌트기반 개발 이전에는 브라우저에서 동적으로 변하는 UI를 표현하기 위해 직접 DOM 객체를 조작하는 명령형 프로그래밍 방식으로 구현했습니다.
💡 명령형은 어떻게(How)를 중요시 여겨서 프로그램의 제어의 흐름과 같은 방법을 제시하고 목표를 명시하지 않는 형태입니다. 선언형은 무엇(What)을 중요시 여겨서 제어의 흐름보다는 원하는 목적을 중요시 여기는 형태입니다.
// Hello, World! 화면에 출력하기
// 순수 javaScript 명령형 코드
const root = document.getElementById('root');
const header = document.createElement('h1');
const headerContent = document.createTextNode(
'Hello, World!'
);
header.appendChild(headerContent);
root.appendChild(header);
Hello, World!를 출력하기 위해 컴퓨터가 수행하는 절차를 일일히 코드로 작성해주어야 함.
React 코드의 경우 내가 UI을 선언하고 render 함수를 호출하면 React가 알아서 절차를 수행해 화면에 출력해줌
// React 코드 (선언적인)
const header = <h1>Hello World</h1>; // jsx
ReactDOM.render(header, document.getElementById('root'));
리액트에서 렌더링이란, 컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업

리액트 앱이 실행되고 첫 렌더링이 일어나면 리액트는 컴포넌트의 루트에서 시작하여 아래쪽으로 쭉 훑으며 컴포넌트가 반환하는 JSX 결과물을 DOM 요소에 반영합니다.
리액트 앱이 실행되면 리액트는 전체 컴포넌트를 렌더링하고 결과물을 DOM에 반영해 브라우저상에 보여주죠. 첫 렌더링을 끝난 이후에 추가로 렌더링을 트리거 하려면 상태를 변경해주면 됩니다.
컴포넌트 상태에 변화가 생기면 리렌더링이 발생합니다. 이때 여러 상태가 변경됐다면 리액트는 이를 큐 자료구조에 넣어 순서를 관리합니다.

브라우저의 렌더링과 리액트의 렌더링은 엄연히 다른 독립적인 프로세스입니다. 렌더링이 완료되고 React가 DOM을 업데이트한 후 브라우저는 화면을 그립니다. 이 프로세스를 "브라우저 렌더링"이라고 하지만 혼동을 피하기 위해 "페인팅"이라고도 합니다.
더 읽어볼 자료 : 브라우저는 어떻게 동작하는가?
지금까지 배운 내용을 활용해서 counter 프로그램을 만들어봅시다.
+ 1 버튼을 누를 때마다 숫자가 + 1 증가 합니다.- 1 버튼을 누를 때마다 숫자가 - 1 감소 합니다.
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return (
<div>
{count}
<button
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
<button
onClick={() => {
setCount(count - 1);
}}
>
-
</button>
</div>
);
}
export default App;
이번 챕터를 시작하기에 앞서 우리가 연습할 새로운 프로젝트를 하나 더 생성해봅시다.
yarn create react-app 프로젝트이름
우선 아래 이미지와 같이 한번 구현해볼까요? 아래의 CSS 치트 시트를 활용해서, 화면과 최대한 똑같이 만들어봅시다!


import React from "react";
function App() {
const all = {
marginTop: "20px",
gap: "20px",
display: "flex",
alignItems: "center",
justifyContent: "center",
};
const styles = {
border: "1px solid green",
width: "100px",
height: "100px",
borderRadius: "10px",
display: "flex",
alignItems: "center",
justifyContent: "center",
};
return (
<div style={all}>
<div style={styles}>감자</div>
<div style={styles}>고구마</div>
<div style={styles}>오이</div>
<div style={styles}>가지</div>
<div style={styles}>옥수수</div>
</div>
);
}
export default App;
import React from "react";
const App = () => {
const style = {
padding: "100px",
display: "flex",
gap: "12px",
};
const squareStyle = {
width: "100px",
height: "100px",
border: "1px solid green",
borderRadius: "10px",
display: "flex",
alignItems: "center",
justifyContent: "center",
};
return (
<div style={style}>
<div style={squareStyle}>감자</div>
<div style={squareStyle}>고구마</div>
<div style={squareStyle}>오이</div>
<div style={squareStyle}>가지</div>
<div style={squareStyle}>옥수수</div>
</div>
);
};
export default App;
import "./App.css";
- 없앤것도 다 넣어주고 뒤에 세미클론 붙혀주기.app-style {
border: 1px solid green;
width: 100px;
height: 100px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.all {
margin-top: 20px;
gap: 20px;
display: flex;
padding: 100px;
}
import React from "react";
import "./App.css"; //css파일 임포트
function App() {
return (
<div className="all"> //
<div className="app-style">감자</div>
<div className="app-style">고구마</div>
<div className="app-style">오이</div>
<div className="app-style">가지</div>
<div className="app-style">옥수수</div>
</div>
);
}
export default App;