리액트를 사용하는 이유?
- 첫째. 컴포넌트로 HTML 페이지의 버튼, 헤더, 카드 등을 부분으로 나눠, 유지보수성 높게 관리할 수 있다.
- 둘째. 스테이트를 사용하여, 특정 값이 바뀔 때마다 바로 화면의 내용을 업데이트할 수 있어, 값의 실시간 반영에 용이하다.
- 셋째. HTML과 JavaScript를 한 곳에서 작성할 수 있어서 편리하다.
- 대충 리액트 프로젝트 시작하는 방법은 다음과 같다.
npm create vite@latest 프로젝트명
cd 프로젝트명
npm install
npm run dev
컴포넌트: 우리가 직접 만드는 태그.
- 컴포넌트: 사용자 정의 태그를 뜻함.
- 기존에 주어진 HTML 태그들... 우리가 그런 태그들을 직접 만들 수 있음.
- 컴포넌트를 사용하여, HTML 페이지의 각 부분을 별도의 함수로 독립할 수 있음. 가독성, 재사용성, 유지보수성이 높아짐.
- 기존에는 여러 페이지에서 공통으로 사용되는 부분에 버그가 발생하면, 모든 페이지를 일일이 수정해야 했음.
- 하지만 중복되는 부분을 컴포넌트로 분리하면, 해당 컴포넌트만 수정하면 됨 -> 효율성 up
- 헤더, 푸터는 물론, 버튼, 카드, 입력 홈 등 실제 UI 요소도 컴포넌트로 분리해서 사용할 수 있음.
컴포넌트 예제
import React from "react";
import "./App.css";
function Header() {
return (
<header>
<h1>
<a href="/">먹고싶은거</a>
</h1>
</header>
);
}
function Nav() {
return (
<nav>
<ol>
<li>
<a href="/read/1">만두</a>
</li>
<li>
<a href="/read/2">순대</a>
</li>
<li>
<a href="/read/3">떡볶이</a>
</li>
</ol>
</nav>
);
}
function Article() {
return (
<article>
<h2>정글에서의 밤은</h2>
언제나 배고프다
</article>
);
}
- 위처럼 컴포넌트 3개를 만들면, 언제든지 재사용할 수 있음!
- 무조건 반환값은 태그 하나에 둘러싸여 있어야 함에 유의할 것.
function App() {
return (
<div>
<Header />
<Nav />
<Article />
</div>
);
}
export default App;
App
컴포넌트에 위에서 만든 세 컴포넌트 삽입

props: 컴포넌트의 속성 겸 매개변수
- HTML 태그에 속성이 있듯이 (e.g.,
<a>
의 href
, <input>
의 type
), 컴포넌트에도 속성이 존재. 이를 props라 부름.
- props의 값을 컴포넌트 함수에서 가져와 사용할 수 있음.
function App() {
const foods = [
{ id: 1, title: "만두" },
{ id: 2, title: "순대" },
{ id: 3, title: "떡볶이" },
];
return (
<div>
<Header title="먹고싶은거" />
<Nav foods={foods} />
<Article title="정글에서의 밤은" body="언제나 배고프다" />
<Article title="수료까지 얼마 남았지?" body="48일 남았대 우와" />
</div>
);
}
title
, body
, foods
등이 각 컴포넌트의 props.
.jsx
파일에선 HTML 태그 내 JS 코드를 작성해야 하는 경우, 중괄호를 사용해야 함
<Nav foods={foods} />
처럼!
const foods
처럼 리스트도 전달 가능.
function Header(props) {
return (
<header>
<h1>
<a href="/">{props.title}</a>
</h1>
</header>
);
}
function Nav(props) {
const food_list = [];
for (let i = 0; i < props.foods.length; i++) {
let t = props.foods[i];
food_list.push(
<li key={t.id}>
<a href={`/read/${t.id}`}>{t.title}</a>
</li>
);
}
return (
<nav>
<ol>{food_list}</ol>
</nav>
);
}
function Article(props) {
return (
<article>
<h2>{props.title}</h2>
{props.body}
</article>
);
}
- 컴포넌트의 매개변수에
props
를 지정하여, props 값을 사용 가능
- 이름은
props
가 아니여도 되는데, 그게 관례임
props.속성이름
을 이용해서 가져옴
Nav
와 같이, 리스트를 순회하는 식으로도 사용 가능!

State: 값이 바뀌면 화면도 바뀐다.
- Prop과 State의 차이점?
- Prop: 부모 컴포넌트(e.g.,
<App/>
)가 자식 컴포넌트(e.g., <Article/>
)에 전달하는 읽기 전용 데이터.
- State: 컴포넌트 내부에서 변할 수 있는 데이터. 상태가 바뀌면, 자동으로 컴포넌트가 재렌더링됨. (즉 화면에서 뜨는 정보가 바뀜)
- 값이 바뀌면 즉시 화면이 바뀌므로, ...를 구현하는 데 쓸모있음.
- cf. Vanilla JS에서는 값이 바뀐 후 UI를 직접 업데이트해야 했었음.
State 예제
let count = 0;
const p = document.getElementById("count");
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
count += 1;
p.textContent = count;
});
useState
함수로 사용 가능.
import { useState } from "react";
로 불러와야 함.
const [state_값, state_변경함수] = useState(state_초기값)
.
state_변경함수(변경할값)
으로 state_값
변경할 수 있음. 이 과정에서 자동으로 컴포넌트가 다시 렌더링됨.
import React from "react";
import "./App.css";
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>사장님 소주 {count}병 주세요!</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
function App() {
return (
<div>
<Counter></Counter>
</div>
);
}
export default App;
- 버튼을 한번 누를때마다
setCount
를 통해 값이 증가. 그리고 직후 Counter
컴포넌트가 리렌더링되어, <p>
태그 내부에 바뀐 값이 갱신됨.
- 아래는 버튼을 연속으로 눌렀을 때의 갱신 결과.


