리액트 프로젝트는 대개 이렇게 구성
src/
├── index.tsx (또는 main.tsx)
├── App.tsx
├── Hello.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
- 브라우저가 index.html을 엽니다. (public/index.html)
- 그 안의 < div id="root" >를 찾습니다.
- index.tsx에서 컴포넌트를 root에 넣습니다.
- 그래서 App.tsx의 UI가 기본 화면으로 보여짐
React에서 컴포넌트는 재사용 가능한 UI 조각
예를 들어 는 화면에 "Hello react study"를 보여주는 작은 UI 블록이고, 여러 곳에서 독립적으로 재사용할 수 있음.
function App() {
return (
<div>
<Hello name="철수" color="red" />
<Hello name="영희" color="blue" />
</div>
);
}
→ 각각 독립적으로 Hello {name}을 다른 색깔로 출력합니다. 이게 컴포넌트의 힘
이라는데 뭔가 와닿지는 않음
그래서 살펴본 기존에 사용하던 AngularJS와 차이
[html]
<!-- HTML -->
<div ng-controller="MyCtrl">
<input ng-model="name">
<p>Hello {{name}}</p>
</div>
[js]
// JS
app.controller("MyCtrl", function($scope) {
$scope.name = "jyj";
});
→ $scope.name이 바뀌면 뷰가 자동 업데이트 되는 양방향 바인딩 구조
function Hello() {
const [name, setName] = useState("juyeon");
return (
<>
<input value={name} onChange={(e) => setName(e.target.value)} />
<p>Hello {name}</p>
</>
);
}
→ React는 state가 바뀌면 해당 컴포넌트를 자동으로 리렌더링
→ 양방향 바인딩은 아니고, 단방향 흐름 (input → setState → UI 갱신)
| 항목 | AngularJS / 전통 JS 방식 | React 방식 |
|---|---|---|
| UI 구성 방식 | HTML 중심 + JS로 조작 (DOM 기반) | 컴포넌트 중심 (JSX, 가상 DOM) |
| 재사용 단위 | DOM 요소 기준 (<div id="x">) | 함수형 컴포넌트 자체 (<MyComponent />) |
| 동작 방식 | 컨트롤러에서 $scope로 데이터 바인딩 | 상태(state)/props 기반의 리렌더링 |
| HTML 조작 | 직접 DOM을 찾아서 수정 (getElementById, ng-model) | 상태(state)가 바뀌면 자동으로 화면 갱신 |
| 상태 관리 | $scope, 양방향 바인딩 | useState, 단방향 바인딩 |
| 모듈화 | Controller + Template + Service 나눔 | UI와 로직이 하나의 컴포넌트에 응집 |
import Hello from "./Hello";
function App() {
return (
<Hello name={'react study'} color={'green'}></Hello>
);
}
export default App;
interface Props {
name: string;
color: string;
}
// 컴포넌트 정의
export const Hello = ({ name, color = "blue" }: Props) => {
return <div style={{ color }}> Hello {name} </div>;
};
/*
// 위를 아래로 풀어서 사용 가능
function Hello({name, color} : Props) {
return <div style={{color}}>Hello {name}</div>
}
*/
export default Hello;