๋ฆฌ์ํธ์์ "UI ์กฐ๊ฐ"์ ๋ง๋๋ ๋จ์์ด๋ค.
๋ฒํผ, ํค๋, ํ๋กํ ์นด๋, ํ์ด์ง ๋ฑ ํ๋์ ํ๋ฉด ์์๋ฅผ ๋ง๋๋ ํจ์์ด๋ค.
// ํ
์คํธ ์์ฑ ํจ์
function sayHello(name) {
return `์๋
, ${name}`;
}
// ํ
์คํธ ๋์ UI (ํ๋ฉด ์์)๋ฅผ ์์ฑ
function Hello(props) {
return <h1>์๋
, {props.name}</h1>;
}
// ์ฌ์ฉ
<Hello name="chori" />
// ๋ธ๋ผ์ฐ์ ์ ์ถ๋ ฅ๋ ๋ชจ์ต
<h1>์๋
, chori</h1>
// HTML
<div class="profile">
<img src="profile.jpg" />
<h2>chori</h2>
</div>
// ๋ฆฌ์กํธ ์ปดํฌ๋ํธ
// Profile.js
import React from 'react';
const Profile = () => {
return (
<div className="profile">
<img src="profile.jpg" />
<h2>chori</h2>
</div>
);
};
export default Profile;
// ์์ Profile.js ์ปดํฌ๋ํธ๋ฅผ ๋ค๋ฅธ ๊ณณ์์ ์ฌ์ฉ ์๋์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
import Profile from './Profile';
const App = () => {
return (
<div>
<h1>๋ด ํ์ด์ง</h1>
<Profile />
</div>
);
};
ํ๋ฉด์ ์ชผ๊ฐ์ ๊ด๋ฆฌํ๊ธฐ ์ฝ๋ค.
์๋ ๋ฐฉ์
HTML / CSS / JS ๋ฅผ ํ๊บผ๋ฒ์ ์์ด ์ฐ๊ธฐ -> ๋ณต์ก, ์ ์ง๋ณด์ ํ๋ฆ
๋ฆฌ์กํธ
ํ๋ฉด์ ๊ธฐ๋ฅ ๋จ์๋ก ๋๋ ์ ๊ด๋ฆฌ
`ํค๋, ๋ฒํผ, ๊ฒ์๊ธ, ๋๊ธ ์ ๊ฐ๊ฐ ์ปดํฌ๋ํธ
-> ์ฌ์ฌ์ฉํ ์ ์๋ค.
์ฌ์ฌ์ฉ์ด ์ฝ๋ค.
ํ ๋ฒ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ฌ ๊ณณ์์ ๋ฐ๋ณตํด์ ์ธ ์ ์๋ค.

๊ฐ์ UI ํ์ ์ฌ๋ฌ ๋ฐ์ดํฐ์ ๋ง๊ฒ ์ธ ์ ์์ด ํจ์จ์ ์ด๋ค.
์ฝ๋ ๊ฐ๋
์ฑ์ ์ฌ๋ ค์ค๋ค.
์
๋ ฅ -> ์ถ๋ ฅ ๊ตฌ์กฐ๊ฐ ๋ผ์ ์ฝ๊ณ ์ดํดํ๊ธฐ ์ฝ๋ค.

์ํ(state)๋ ์ด๋ฒคํธ๋ ํจ์ ์์์ ์ฒ๋ฆฌ ๊ฐ๋ฅ

UI + ๋์ + ๋ฐ์ดํฐ ์ํ๋ฅผ ํ ํจ์(์ปดํฌ๋ํธ) ์์์ ์ฒ๋ฆฌ ๊ฐ๋ฅํด์ ๊ธฐ๋ฅ ๋จ์๋ก ์ ๋ฆฌํ ์ ์๋ค.
์ปดํฌ๋ํธ์ ์ ๋ฌํ๋ ๊ฐ(๋ฐ์ดํฐ)
๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ค ๋ ์ฌ์ฉํ๋ค.
props์ ๊ฐ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๊ฐ ์๋ฆฌ๋จผํธ๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฐ์ผ๋ก ์ฝ๊ธฐ ์ ์ฉ์ด๋ค.
-> ์์ ๋ถ๊ฐ, ํญ์ ๊ฐ์ ๊ฐ ์ ์ง
๋ค๋ฅธ props์ ๊ฐ์ผ๋ก ์๋ฆฌ๋จผํธ๋ฅผ ์์ฑํ๋ ค๋ฉด ์๋ก์ด ๊ฐ์ ์ปดํฌ๋ํธ์ ์ ๋ฌํ์ฌ ์๋ก ์๋ฆฌ๋จผํธ๋ฅผ ์์ฑํ๋ค.
// ๋ถ๋ชจ
function App() {
return (
<div>
<Greeting name="chori" />
</div>
);
}
// ์์
function Greeting(props) {
return <h1>์๋
, {props.name}!</h1>;
}
// ๊ฒฐ๊ณผ
// ์๋
, chori!
// ๊ตฌ์กฐ ๋ถํด ๊ฐ๋ฅ ( ๊ฐ์ฒด๋ ๋ฐฐ์ด์์ ๊ฐ๋ง ๊น๋ํ๊ฒ ๊บผ๋ด๋ ๋ฌธ๋ฒ)
function Greeting({ name }) {
return <h1>์๋
, {name}!</h1>;
}
// ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ
<Greeting name="์ฒ ์" /> // ์๋
, ์ฒ ์!
<Greeting name="์ํฌ" /> // ์๋
, ์ํฌ!
class ํค์๋๋ก ์ ์ํ๋ ์ปดํฌ๋ํธ๋ก state ๊ธฐ๋ฅ ๋ฐ ๋ผ์ดํ์ฌ์ดํด ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ณ ์์ ๋ฉ์๋๋ฅผ ์ ์ํ ์ ์๋ค.
render ํจ์๊ฐ ๊ผญ ์์ด์ผ ํ๊ณ , ๋ณด์ฌ์ค์ผํ JSX๋ฅผ ๋ฐํํด์ผํ๋ค.
React์์ ์ฌ๊ณตํ๋ Component๋ผ๋ ํด๋์ค๋ฅผ ์์ํด์ ๋ง๋ค ์ ์๋ค.
Class ์๋ ์ํ, ๋ฐ์ดํฐ๋ฅผ ๋ด์ ์ ์๋ state ๋ผ๋ ์ค๋ธ์ ํธ๊ฐ ๋ค์ด์๋ค. state์ ๋ด์ฉ์ด ์
๋ฐ์ดํธ ๋ ๋๋ง๋ค render ํจ์๊ฐ ํธ์ถ๋๋ฉฐ ์
๋ฐ์ดํธ๋ ๋ด์ฉ์ ๋ณด์ฌ์ค๋ค.
๋ผ์ดํ ์ฌ์ดํด์ ๋ฐ๋ผ ํจ์๋ฅผ ๊ตฌํํด ๋๊ณ ๋ฆฌ์กํธ๊ฐ ์ด๊ฑธ ์๋์ผ๋ก ์คํ์ํจ๋ค.
import React, { Component } from 'react';
class MyComponent extends Component {
render() {
return <h1>์๋
ํ์ธ์!</h1>;
}
}
// props๋ this.props๋ก ์ ๊ทผ
class Hello extends Component {
render() {
return <p>์๋
ํ์ธ์, {this.props.name}๋!</p>;
}
}
์ปดํฌ๋ํธ ๋ด๋ถ์์ ๊ด๋ฆฌ๋๋ ๋ฐ์ดํฐ๋ก, ์ฌ์ฉ์์ ๋์์ด๋ ์ด๋ฒคํธ ๋ฑ์ ๋ฐ๋ผ ๋ณํ ์ ์๋ ๊ฐ์ด๋ค.
// ๋ฒํผ์ ๋๋ฅผ ๋ ๋ง๋ค ์ซ์๊ฐ ๋ฐ๋๋ ๊ฒฝ์ฐ
const [count, setCount] = useState(0);
// count ๊ฐ state
// state์ ๋ฐ๋ผ ์ ๋์ ์ผ๋ก ๋ณํ๋ UI
// state๊ฐ ๋ณํ๋ฉด (์ฌ์ฉ์๊ฐ ํด๋ฆญํ๊ฑฐ๋ ์ฒดํฌ ๊ฐ์ ์ํธ์์ฉ ๋ฑ๋ฑ)
// ๊ทธ ๊ฐ์ ๊ธฐ๋ฐ์ผ๋ก ์๋์ผ๋ก ํ๋ฉด์ ๋ ๋๋ง
<p>ํ์ฌ ์ซ์: {count}</p>
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // count ์ด๊ธฐ๊ฐ์ 0
const increase = () => {
setCount(count + 1);
};
return (
<div>
<p>ํ์ฌ ์นด์ดํธ: {count}</p>
<button onClick={increase}>+1</button>
</div>
);
}
/*
useState(0) โ ์ด๊ธฐ๊ฐ์ 0
count โ ํ์ฌ ์ํ ๊ฐ
setCount โ ์๋ก์ด ๊ฐ์ผ๋ก ์ํ๋ฅผ ๋ณ๊ฒฝ
setCount()๊ฐ ํธ์ถ๋๋ฉด, ์๋์ผ๋ก ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ ๋๋ง
*/
state์ ๋ผ์ดํ์ฌ์ดํด API ์ฌ์ฉ์ด ๋ถ๊ฐํ๋ค.
-> Hook ๊ธฐ๋ฅ์ด ๋์
๋๋ฉด์ ํด๊ฒฐ

ํญ์ ๋๋ฌธ์๋ก ์์ํด์ผํ๋ค.
๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ์ํ
๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ๋ฐ์ดํฐ(์ปดํฌ๋ํธ ๋ด๋ถ์์ ๋ฐ๋ ์ ์๋ ๊ฐ)
ํด๋์ค ์ปดํฌ๋ํธ์ ๊ฒฝ์ฐ state๋ฅผ ์์ฑ์์์ ์ ์(state ๋ณ๊ฒฝํ ๋๋ setState()๋ฅผ ์ฌ์ฉ)
ํจ์ํ ์ปดํฌ๋ํธ๋ useState()๋ผ๋ ํ ์ ์ฌ์ฉํ์ฌ ์ ์
ํด๋์คํ ์ปดํฌ๋ํธ์ state๋ฅผ ์ค์ ํ๋ ๊ฒฝ์ฐ ์์ฑ์(constructor) ๋ฉ์๋๋ฅผ ์ค์ ํ๋ค.
๋ฐ๋์ super(props)๋ฅผ ํธ์ถํด์ค์ผํ๊ณ , ์ด ํจ์๊ฐ ํธ์ถ๋๋ฉด ํ์ฌ ํด๋์คํ ์ปดํฌ๋ํธ๊ฐ ์์๋ฐ๊ณ ์๋ ๋ฆฌ์กํธ์ ์ปดํฌ๋ํธ ํด๋์ค๊ฐ ์ง๋ ์์ฑ์ ํจ์๋ฅผ ํธ์ถํด ์ค๋ค.
class Counter extends Component {
constructor(props) {
super(props); // ๋ฐ๋์ ํธ์ถํด์ผ ํจ!
// this.state ์ด๊ธฐํ
this.state = {
count: 0
};
}
handleIncrement = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>ํ์ฌ ์นด์ดํธ: {this.state.count}</p>
<button onClick={this.handleIncrement}>+1</button>
</div>
);
}
}
React์ ํจ์ํ ์ปดํฌ๋ํธ์์ ์ํ(state)๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ Hook ์ด๋ค.
์ปดํฌ๋ํธ ์์์ ๊ฐ์ ์ ์ฅํ๊ณ ๋ฐ๋ ๋๋ง๋ค ์๋์ผ๋ก ํ๋ฉด(UI) ๋ค์ ๊ทธ๋ฆฌ๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
import React, { useState } from 'react';
function Counter() {
// const [ํ์ฌ ์ํ ๊ฐ, ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์] = userState('์ด๊ธฐ๊ฐ');
// ์ด๊ธฐ๊ฐ์ ๋ชจ๋ ์๋ฃํ์ ๋ฐ์ ์ ์๋ค.
// ํด๋์คํ ์ปดํฌ๋ํธ๋ ํญ์ ๊ฐ์ฒด
const [count, setCount] = useState(0); // ์ํ ๋ณ์ ์ ์ธ
return (
<div>
<p>ํ์ฌ ์นด์ดํธ: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
๊ตฌ์กฐ ๋ถํด ๋ง์ด ์จ๋ณผ ๊ฒ
์ต์ํ์ง ์์์ ์ฝ์ด๋ ํด์ํ๊ธฐ ์ด๋ ต๋ค.
์์๋ฅผ ๋ง๋ค๋ผ๊ณ ํด๋ ์์ฑํ๊ธฐ ์ด๋ ต๋ค.