React์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ธ State์ Props
State์ Props ์ฐจ์ด
Props: ์ธ๋ถ๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ๊ฐ (์ธ์์ ๊ฐ์ด ๋๊ฒจ๋ฐ์ ์ ์๋ค.) ํจ๋ถ๋ก ๋ณ๊ฒฝ๋ ์ ์๋ ์ฝ๊ธฐ ์ ์ฉ(read-only) ๊ฐ์ฒด
State: ์ปดํฌ๋ํธ ๋ด๋ถ์์ ๋ณํํ๋ ๊ฐ
์ด๋ค ๊ฒ์ด State์ Props์ ์ ํฉํ ๊น?
์ด๋ฆ / Props
์ฑ๋ณ / Props
๋์ด / State (๋งค๋ ๋ฐ๋)
ํ์ฌ ์ฌ๋ ๊ณณ / State (์ด์ฌํ ๋๋ง๋ค ๋ฐ๋)
์ทจ์ ์ฌ๋ถ / State (๋ด ์ํ์ ๋ฐ๋ผ ๋ฐ๋)
๊ฒฐํผ/ ์ฐ์ ์ฌ๋ถ / State (๋ด ์ํ์ ๋ฐ๋ผ ๋ฐ๋)
Toggle Switch / State (์ค์์น๋ฅผ on/off ์ฌ๋ถ์ ๋ฐ๋ผ ๋ฐ๋ // isOn:true, isOn:false)
Props์ ํน์ง
- ์ปดํฌ๋ํธ์ ์์ฑ(property)์ ์๋ฏธํ๋ค.
- ๋ณํ์ง ์๋ ์ธ๋ถ(๋ถ๋ชจ ์ปดํฌ๋ํธ(์์ ์ปดํฌ๋ํธ))๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ๊ฐ์ด๊ณ , ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ํด๋น ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ง ์์ฑ์ ํด๋นํ๋ค.
- props๋ก ์ด๋ค ํ์ ์ ๊ฐ๋ ๋ฃ์ด ์ ๋ฌํ ์ ์๋๋ก props๋ ๊ฐ์ฒด์ ํํ์ด๋ค.
- props๋ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ณ๊ฒฝ๋ถ๊ฐ!!
- ์ดํด ํ์ React ์ปดํฌ๋ํธ๋ JavaScript ํจ์์ ํด๋์ค๋ก, props๋ฅผ ํจ์์ ์ ๋ฌ์ธ์(arguments)์ฒ๋ผ ์ ๋ฌ๋ฐ์ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉด์ ์ด๋ป๊ฒ ํ์๋๋์ง๋ฅผ ๊ธฐ์ ํ๋ React ์๋ฆฌ๋จผํธ๋ฅผ ๋ฐํํ๋ค. ๋ฐ๋ผ์, ์ปดํฌ๋ํธ๊ฐ ์ต์ด ๋ ๋๋ง ๋ ๋ ํ๋ฉด์ ์ถ๋ ฅํ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ์ด๊น๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
Props ์ฌ์ฉ๋ฐฉ๋ฒ
- ํ์ ์ปดํฌ๋ํธ์ ์ ๋ฌํ๊ณ ์ ํ๋ ๊ฐ(data)๊ณผ ์์ฑ์ ์ ์ํ๋ค.
- props๋ฅผ ์ด์ฉํ์ฌ ์ ์๋ ๊ฐ๊ณผ ์์ฑ์ ์ ๋ฌํ๋ค.
- ์ ๋ฌ๋ฐ์ props๋ฅผ **๋ ๋๋งํ๋ค.
** ๋ ๋๋ง์ด๋ HTML, CSS, ์๋ฐ์คํฌ๋ฆฝํธ ๋ฑ ๊ฐ๋ฐ์๊ฐ ์์ฑํ ๋ฌธ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ์ถ๋ ฅ๋๋ ๊ณผ์ ์ ๋งํ๋ค.
์ฆ, ํ๋ฉด์ ํ์ํ ์น ํ์ด์ง๋ฅผ ๋ง๋๋ ๊ณผ์ ์ ๋ปํ๋ค.
state ๋ค๋ฃจ๊ธฐ
<useState ์ฌ์ฉ>
1. React๋ก๋ถํฐ useState ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ
import { useState } from "react";
2. useState ๋ฅผ ์ปดํฌ๋ํธ ์์์ ํธ์ถํ๊ธฐ
์ผ๋ฐ์ ์ธ ๋ณ์๋ ํจ์๊ฐ ๋๋ ๋ ์ฌ๋ผ์ง์ง๋ง, state ๋ณ์๋ React์ ์ํด ํจ์๊ฐ ๋๋๋ ์ฌ๋ผ์ง์ง ์๋๋ค.
์๋ ์์์ isChecked, setIsChecked ๋ useState ์ ๋ฆฌํด๊ฐ์ ๊ตฌ์กฐ ๋ถํด ํ ๋นํ ๋ณ์์ด๋ค.
๐ useState ๋ฌธ๋ฒ ์์
function CheckboxExample() {
// ์๋ก์ด state ๋ณ์๋ฅผ ์ ์ธํ๊ณ , ์ด๊ฒ์ isChecked ๋ผ๊ณ ๋ถ๋ฅธ๋ค๋ผ๋ ๋ป
const [isChecked, setIsChecked] = useState(false);
๐ useState ๊ตฌ์กฐ ๋ถํด ํ ๋น ์์
function CheckboxExample() {
// 1๋ฒ ์ฝ๋๋ฅผ ํ์ด์ฐ๋ฉด
const [isChecked, setIsChecked] = useState(false); // 1๋ฒ
//...
// 2๋ฒ ์ฝ๋์ ๊ฐ๋ค.
const stateHookArray = useState(false); // 2๋ฒ
const isChecked = stateHookArray[0];
const setIsChecked = stateHookArray[1];
}
useState ๋ฅผ ํธ์ถํ๋ฉด ๋ฐฐ์ด์ ๋ฐํํ๋๋ฐ, ๋ฐฐ์ด์ 0๋ฒ์งธ ์์๋ ํ์ฌ state ๋ณ์์ด๊ณ , 1๋ฒ์งธ ์์๋ ์ด ๋ณ์๋ฅผ ๊ฐฑ์ ํ ์ ์๋ ํจ์์ด๋ค. useState ์ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ ๊ฐ์ state์ ์ด๊น๊ฐ์ด๋ค.
const [state ์ ์ฅ ๋ณ์, state ๊ฐฑ์ ํจ์] = useState(์ํ ์ด๊ธฐ ๊ฐ);
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false);
- isChecked : state๋ฅผ ์ ์ฅํ๋ ๋ณ์
- setIsChecked : state isChecked ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์
- useState : state hook
- false : state ์ด๊น๊ฐ
์ด state ๋ณ์์ ์ ์ฅ๋ ๊ฐ์ ์ฌ์ฉํ๋ ค๋ฉด JSX ์๋ฆฌ๋จผํธ ์์ ์ง์ ๋ถ๋ฌ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
์ฌ๊ธฐ์๋ isChecked ๊ฐ boolean ๊ฐ์ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ true or false ์ฌ๋ถ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋ณด์ด๋๋ก ์ผํญ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ค.
๐ JSX์์ ์ผํญ์ฐ์ฐ์ ์ฌ์ฉ ์์
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
<state ๊ฐฑ์ ํ๊ธฐ>
- state๋ฅผ ๊ฐฑ์ ํ๋ ค๋ฉด state ๋ณ์๋ฅผ ๊ฐฑ์ ํ ์ ์๋ ํจ์์ธ setIsChecked ๋ฅผ ํธ์ถํ๋ค.
๐ ์ฒดํฌ๋ฐ์ค ์ปดํฌ๋ํธ ์์
์ฌ์ฉ์๊ฐ ์ฒดํฌ๋ฐ์ค ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด onChange ์ด๋ฒคํธ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์์ธ handleChecked ๋ฅผ ํธ์ถํ๊ณ , ์ด ํจ์๊ฐ setIsChecked ๋ฅผ ํธ์ถํ๋ค. setIsChecked ๊ฐ ํธ์ถ๋๋ฉด ํธ์ถ๋ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ isChecked ๋ณ์๊ฐ ๊ฐฑ์ ๋๋ฉฐ, React๋ ์๋ก์ด isChecked ๋ณ์๋ฅผ CheckboxExample ์ปดํฌ๋ํธ์ ๋๊ฒจ ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ๋ ๋๋ง ํ๋ค.
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false);
const handleChecked = (event) => {
setIsChecked(event.target.checked);
};
return (
<div className="App">
<input type="checkbox" checked={isChecked} onChange={handleChecked} />
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
</div>
);
}
import React, { useState } from "react";
import "./styles.css";
function CheckboxExample() {
console.log("rerendered?");
const [isChecked, setIsChecked] = useState(false);
const handleChecked = (event) => {
setIsChecked(event.target.checked);
};
return (
<div className="App">
<input type="checkbox" checked={isChecked} onChange={handleChecked} />
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
</div>
);
}
export default CheckboxExample;
์ฃผ์!
React state๋ ์ํ ๋ณ๊ฒฝ ํจ์ ํธ์ถ๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
๊ฐ์ ๋ก ๋ณ๊ฒฝ์ ์๋ํ๋ฉด ์๋๋ค.
์ํ ๋ณ๊ฒฝ ํจ์ ์ฌ์ฉ์ React์ ๊ฐ๋ฐ์์ ์ฝ์์ด๊ธฐ ๋๋ฌธ์ ์ง์ผ์ฃผ์ด์ผ ํ๋ค.
๊ฐ์ ๋ก ๋ณ๊ฒฝ์ ์๋ํ๋ฉด, ๋ฆฌ๋ ๋๋ง์ด ๋์ง ์๋๋ค๊ฑฐ๋, state๊ฐ ์ ๋๋ก ๋ณ๊ฒฝ๋์ง ์๋๋ค.
React์ ์ด๋ฒคํธ ์ฒ๋ฆฌ(์ด๋ฒคํธ ํธ๋ค๋ง; Event handling)
- DOM์ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฐฉ์๊ณผ ์ ์ฌํ๋ค.
- React ์์ ์ด๋ฒคํธ๋ ์นด๋ฉ ์ผ์ด์ค(camelCase)๋ฅผ ์ฌ์ฉํ๋ค.
- JSX๋ฅผ ์ฌ์ฉํ์ฌ ํจ์๋ก ์ด๋ฒคํธ ์ฒ๋ฆฌ ํจ์(์ด๋ฒคํธ ํธ๋ค๋ฌ; Event handler)๋ฅผ ์ ๋ฌํ๋ค.
๐ ๋ฆฌ์กํธ์ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฐฉ์
<button onClick={handleEvent}>Event</button>
๐ HTML์์ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฐฉ์
<button onclick="handleEvent()">Event</button>
<React ์์์์ฃผ ์ฌ์ฉ๋๋ ์ด๋ฒคํธ>
onChange
React ์์๋ <input> <textarea> <select>์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ์ ์๋ ์ ๋ ฅ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก ์ปดํฌ๋ํธ์ state ๋ก ๊ด๋ฆฌํ๊ณ ์ ๋ฐ์ดํธ ํ๋ค.
onChange ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด e.target.value ๋ฅผ ํตํด ์ด๋ฒคํธ ๊ฐ์ฒด์ ๋ด๊ฒจ์๋ input ๊ฐ์ ์ฝ์ด์ฌ ์ ์๋ค. ์ปดํฌ๋ํธ return ๋ฌธ ์์ input ํ๊ทธ์ value ์ onChange ๋ฅผ ๋ฃ์ด์ฃผ์๋ค. onChange ๋ input ์ ํ ์คํธ๊ฐ ๋ฐ๋ ๋๋ง๋ค ๋ฐ์ํ๋ ์ด๋ฒคํธ์ด๋ค. ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด handleChange ํจ์๊ฐ ์๋ํ๋ฉฐ, ์ด๋ฒคํธ ๊ฐ์ฒด์ ๋ด๊ธด input ๊ฐ์ setState ๋ฅผ ํตํด ์๋ก์ด state ๋ก ๊ฐฑ์ ํ๋ค.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<h1>{name}</h1>
</div>
)
};
onClick
onClick ์ด๋ฒคํธ๋ ๋ง ๊ทธ๋๋ก ์ฌ์ฉ์๊ฐ ํด๋ฆญ์ด๋ผ๋ ํ๋์ ํ์์ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ด๋ค.
๋ฒํผ์ด๋ <a> tag ๋ฅผ ํตํ ๋งํฌ ์ด๋ ๋ฑ๊ณผ ๊ฐ์ด ์ฃผ๋ก ์ฌ์ฉ์์ ํ๋์ ๋ฐ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐ์ํด์ผ ํ ๋ ์์ฃผ ์ฌ์ฉํ๋ ์ด๋ฒคํธ์ด๋ค.
๐ ๋ฒํผ ํด๋ฆญ ์ input tag ์ ์ ๋ ฅํ ์ด๋ฆ์ด alert์ ํตํด ์๋ฆผ ์ฐฝ์ด ํ์ ๋๋ค.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={alert(name)}>Button</button>
<h1>{name}</h1>
</div>
);
};
โฅ onClick ์ด๋ฒคํธ์ alert(name) ํจ์๋ฅผ ๋ฐ๋ก ํธ์ถํ๋ฉด ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋ ํจ์ ์์ฒด๊ฐ ์๋ ํจ์ ํธ์ถ์ ๊ฒฐ๊ณผ๊ฐ onClick ์ ์ ์ฉ๋๋ค. ๋๋ฌธ์ ๋ฒํผ์ ํด๋ฆญํ ๋๊ฐ ์๋, ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋์ alert ์ด ์คํ๋๊ณ ๋ฐ๋ผ์ ๊ทธ ๊ฒฐ๊ณผ์ธ undefined (ํจ์๋ ๋ฆฌํด ๊ฐ์ด ์์ ๋ undefined ๋ฅผ ๋ฐํํฉ๋๋ค.) ๊ฐ onClick ์ ์ ์ฉ๋์ด ํด๋ฆญํ์ ๋ ์๋ฌด๋ฐ ๊ฒฐ๊ณผ๋ ์ผ์ด๋์ง ์๋๋ค.
๐ onClick ์ด๋ฒคํธ์ ํจ์๋ฅผ ์ ๋ฌํ ๋๋ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ์๋๋ผ ์๋์ ๊ฐ์ด ๋ฆฌํด๋ฌธ ์์์ ํจ์๋ฅผ ์ ์ํ๊ฑฐ๋ ๋ฆฌํด๋ฌธ ์ธ๋ถ์์ ํจ์๋ฅผ ์ ์ ํ ์ด๋ฒคํธ์ ํจ์ ์์ฒด๋ฅผ ์ ๋ฌํด์ผ ํ๋ค. ๋จ, ๋ ๊ฐ์ง ๋ฐฉ๋ฒ ๋ชจ๋ arrow function ์ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ์ ์ํ์ฌ์ผ ํด๋น ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ง state์ ํจ์๋ค์ด ์ ๊ทผํ ์ ์๋ค.
// ํจ์ ์ ์ํ๊ธฐ
return (
<div>
...
<button onClick={() => alert(name)}>Button</button>
...
</div>
);
};
// ํจ์ ์์ฒด๋ฅผ ์ ๋ฌํ๊ธฐ
const handleClick = () => {
alert(name);
};
return (
<div>
...
<button onClick={handleClick}>Button</button>
...
</div>
);
};
- ์ปดํฌ๋ํธ๋ ์ปดํฌ๋ํธ ๋ฐ๊นฅ์์ props๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ง์น ์ธ์(arguments) ํน์ ์์ฑ(attributes)์ฒ๋ผ ์ ๋ฌ๋ฐ์ ์ ์๋ค.
- ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ฃผ์ฒด๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋๋ค. ์ด๋ ๋ฐ์ดํฐ ํ๋ฆ์ด ํํฅ์(top-down) ์์ ์๋ฏธํ๋ค.
- ๋ฆฌ์กํธ๋ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ(one-way data flow)!!