๐ ๊ฐ์ฒด state ์ ๋ฐ์ดํธ
state๋ ๊ฐ์ฒด๋ฅผ ํฌํจํด์ ์ด๋ค ์ข ๋ฅ์ javascript ๊ฐ์ด๋ ์ ์ฅํ ์ ์์ต๋๋ค.
ํ์ง๋ง react state์ ์๋ ๊ฐ์ฒด๋ฅผ ์ง์ ๋ณ์ดํด์๋ ์๋ฉ๋๋ค. ⇒ ๊ฐ์ฒด์ ๋ถ๋ณ์ฑ
๋์ ๊ฐ์ฒด๋ฅผ ์ ๋ฐ์ดํธํ๋ ค๋ฉด ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ (ํน์ ๊ธฐ์กด ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ ๋ง๋ค๊ณ = spread ์ฐ์ฐ์) ํด๋น ๋ณต์ฌ๋ณธ์ ์ฌ์ฉํ๋๋ก state๋ฅผ ์ค์ ํด์ผ ํฉ๋๋ค.
- react state์์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ
- ์ค์ฒฉ๋ ๊ฐ์ฒด๋ฅผ ๋ณ์ดํ์ง ์๊ณ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ
- ๋ถ๋ณ์ฑ์ด๋ ๋ฌด์์ด๋ฉฐ, ๋ถ๋ณ์ฑ์ ๊นจ๋จ๋ฆฌ์ง ์๋ ๋ฐฉ๋ฒ
- Immer๋ก ๊ฐ์ฒด ๋ณต์ฌ๋ฅผ ๋ ๋ฐ๋ณต์ ์ผ๋ก ๋ง๋๋ ๋ฐฉ๋ฒ
๐ ๋ณ์ด๋ ๋ฌด์์ธ๊ฐ?
javascript ๊ฐ์ ๋ถ๋ณ, ๋ณ์ดํ ์ ์๊ฑฐ๋ ์ฝ๊ธฐ์ ์ฉ→ ๋ค์ ๋ ๋๋ง์ ์ผ์ผ์ผ์ ๊ฐ์ ๋ณํ๊ฐ๋ฅ
const [x, setX] = useState(0);
setX(5);
X state๊ฐ 0์์ 5๋ก ๋ณ๊ฒฝ๋์์ง๋ง ์ซ์ 0 ์์ฒด๋ ๋ณ๊ฒฝ๋์ง ์์์ต๋๋ค. javascript์์๋ ์ซ์, ๋ฌธ์์ด, ๋ถ๋ฆฌ์ธ๊ณผ ๊ฐ์ ๋นํธ์ธ ์์ ์๋ฃํ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์์ ํ์ (Primitive Type)
์์ ํ์ ์ ๋ชจ๋ ํ๋์ ๊ฐ์ ๋ด๊ณ ์์ต๋๋ค.
- ๋ฌธ์(string)
- ์ซ์(number)
- bigint
- ๋ถ๋ฆฌ์ธ(boolean)
- null
- undefined
- ์ฌ๋ณผ(symbol) => ES6๋ถํฐ ์ถ๊ฐ๋ ํ์
const [position, setPosition] = useState({ x: 0, y: 0 });
๊ฐ์ฒด ์์ฒด์ ๋ด์ฉ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๊ฐ๋ฅํฉ๋๋ค. → ๋ณ์ด
์ซ์, ๋ถ๋ฆฌ์ธ, ๋ฌธ์์ด๊ณผ ๊ฐ์ด ๋ถ๋ณํ๋ ๊ฒ์ฒ๋ผ ์ทจ๊ธํด์ผ ํจ, ์ง์ ๋ณ์ดํ๋ ๋์ ๊ต์ฒดํด์ผ ํฉ๋๋ค.
๐ state๋ฅผ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ทจ๊ธํ์ธ์
๋ค์ ๋งํด state์ ๋ฃ๋ ๋ชจ๋ javascript ๊ฐ์ฒด๋ฅผ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ทจ๊ธํด์ผ ํฉ๋๋ค.
onPointerMove={e => {
position.x = e.clientX;
position.y = e.clientY;
}}
์ด์ ๋ ๋๋ง์์ position์ ํ ๋น๋ ๊ฐ์ฒด๋ฅผ ์์ ํฉ๋๋ค. ํ์ง๋ง state ์ค์ ์ ํจ์๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด react๋ ๊ฐ์ฒด๊ฐ ๋ณ์ด๋์๋ค๋ ์ฌ์ค์ ์์ง ๋ชปํฉ๋๋ค. ๊ทธ๋์ react๋ ์๋ฌด ๋ฐ์๋ ํ์ง ์์ต๋๋ค.
state ๋ณ์ด๋ ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์๋ํ ์ ์์ง๋ง ๊ถ์ฅํ์ง ์์ต๋๋ค. ๋ ๋๋ง์์ ์ ๊ทผํ ์ ์๋ state๊ฐ์ ์ฝ๊ธฐ์ ์ฉ์ผ๋ก ์ทจ๊ธํด์ผ ํฉ๋๋ค.
onPointerMove={e => {
setPosition({
x: e.clientX,
y: e.clientY
});
}}
์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ state ์ค์ ์ ํจ์์ ์ ๋ฌ → ๋ฆฌ๋ ๋๋ง !
setPosition์ผ๋ก react์ 1. position์ ์ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ, 2. ์ปดํฌ๋ํธ ๋ค์ ๋ ๋๋ง ์ํด
๐ ์ ๊ฐ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด ๋ณต์ฌํ๊ธฐ
position ๊ฐ์ฒด๋ ํญ์ ํ์ฌ ์ปค์ ์์น์์ ์๋ก ๋ง๋ค์ด์ก์ต๋๋ค. ๊ทธ๋ฌ๋ ์ข ์ข ๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ์๋ก ๋ง๋๋ ๊ฐ์ฒด์ ์ผ๋ถ๋ก ํฌํจ์ํค๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, form์ ์๋ ํ๋์ ํ๋๋ง ์ ๋ฐ์ดํธํ๊ณ ๋ค๋ฅธ ๋ชจ๋ ํ๋๋ ์ด์ ๊ฐ์ ์ ์งํ๊ณ ์ถ์ ์ ์์ต๋๋ค.
import { useState } from 'react';
export default function Form() { const [person, setPerson] = useState({ firstName: 'Barbara', lastName: 'Hepworth', email: 'bhepworth@sculpture.com' });
function handleFirstNameChange(e) { person.firstName = e.target.value; }
function handleLastNameChange(e) { person.lastName = e.target.value; }
function handleEmailChange(e) { person.email = e.target.value; }
return ( <> <label> First name: <input value={person.firstName} onChange={handleFirstNameChange} /> </label> <label> Last name: <input value={person.lastName} onChange={handleLastNameChange} /> </label> <label> Email: <input value={person.email} onChange={handleEmailChange} /> </label> <p> {person.firstName}{' '} {person.lastName}{' '} ({person.email}) </p> </> ); }
์ด ์ค์ ์ด์ ๋ ๋๋ง ์์ state๋ฅผ ๋ณ์ดํฉ๋๋ค
person.firstName = e.target.value;
์ํ๋ ๋์์ ์ป์ ์ ์๋ ๊ฐ์ฅ ์์ ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ฐ์ฑ๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ setPerson์ ์ ๋ฌํ๋ ๊ฒ์ ๋๋ค. ํ์ง๋ง ์ฌ๊ธฐ์๋ ํ๋ ์ค ํ๋๋ง ๋ณ๊ฒฝ๋์์ผ๋ฏ๋ก ๊ธฐ์กด ๋ฐ์ดํฐ๋ ๋ณต์ฌํ๊ณ ์ถ์ต๋๋ค !
setPerson({
firstName: e.target.value, // New first name from the input
// input์์ ๋ฐ์์จ ์๋ก์ด first name
lastName: person.lastName,
email: person.email
});
๋ชจ๋ ์์ฑ์ ๊ฐ๋ณ์ ์ผ๋ก ๋ณต์ฌํ ํ์๊ฐ ์๋๋ก …๊ฐ์ฒด ์ ๊ฐ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
setPerson({
...person, // Copy the old fields
// ์ด์ ํ๋๋ฅผ ๋ณต์ฌํฉ๋๋ค.
firstName: e.target.value // But override this one
// ๋จ, first name๋ง ๋ฎ์ด์์๋๋ค.
});
๊ฐ ์ ๋ ฅ ํ๋์ ๋ํด ๋ณ๋์ state ๋ณ์๋ฅผ ์ ์ธํ์ง ์์ ๊ฒ์ ์ฃผ๋ชฉํ์ธ์. ํฐ ์์์ ๊ฒฝ์ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ฐ์ดํธํ๊ธฐ๋ง ํ๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ ๊ทธ๋ฃนํํ์ฌ ๋ณด๊ดํ๋ ๊ฒ์ด ๋งค์ฐ ํธ๋ฆฌํฉ๋๋ค.
function handleFirstNameChange(e) { setPerson({ ...person, firstName: e.target.value }); }
return ( <> <label> First name: <input value={person.firstName} onChange={handleFirstNameChange} /> </label>
…์ ๊ฐ ๊ตฌ๋ฌธ์ ์์ ๊ตฌ๋ฌธ์ผ๋ก ํ ๋จ๊ณ ๊น์ด๋ง ๋ณต์ฌํ๋ค๋ ์ ์ ์ ์ํ์ธ์. ์๋๋ ๋น ๋ฅด์ง๋ง ์ค์ฒฉ๋ ํ๋กํผํฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ ค๋ฉด ๋๋ฒ ์ด์ ์ฌ์ฉํด์ผ ํ๋ค๋ ๋ป์ ๋๋ค.
๐ ์ค์ฒฉ๋ ๊ฐ์ฒด ์ ๋ฐ์ดํธํ๊ธฐ
const [person, setPerson] = useState({
name: 'Niki de Saint Phalle',
artwork: {
title: 'Blue Nana',
city: 'Hamburg',
image: 'https://i.imgur.com/Sd1AgUOm.jpg',
}
});
person.artwork.city๋ฅผ ์ ๋ฐ์ดํธํ๋ ค๋ฉด ๋ณ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ์ด ๋ช ํํฉ๋๋ค.
person.artwork.city = ‘new delhi’;
ํ์ง๋ง react์์๋ state๋ฅผ ๋ถ๋ณ์ผ๋ก ์ทจ๊ธํฉ๋๋ค. city๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ฉด ๋จผ์ ์ artwork ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ค์ ์ artwork๋ฅผ ๊ฐ๋ฆฌํค๋ ์๋ก์ด ์ฌ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
const nextArtwork = { ...person.artwork, city: 'New Delhi' };
const nextPerson = { ...person, artwork: nextArtwork };
setPerson(nextPerson);
๋๋ ๋จ์ผ ํจ์ ํธ์ถ๋ก ์์ฑ๊ฐ๋ฅ
setPerson({
...person, // Copy other fields
artwork: { // but replace the artwork
// ๋์ฒดํ artwork๋ฅผ ์ ์ธํ ๋ค๋ฅธ ํ๋๋ฅผ ๋ณต์ฌํฉ๋๋ค.
...person.artwork, // with the same one
city: 'New Delhi' // but in New Delhi!
// New Delhi'๋ ๋ฎ์ด ์์ด ์ฑ๋ก ๋๋จธ์ง artwork ํ๋๋ฅผ ๋ณต์ฌํฉ๋๋ค!
}
});
๐ Immer๋ก ๊ฐ๊ฒฐํ ์ ๋ฐ์ดํธ ๋ก์ง ์์ฑ
state๊ฐ ๊น๊ฒ ์ค์ฒฉ๋ ๊ฒฝ์ฐ ๊ทธ๊ฒ์ ํํํ๊ฒ ๋ง๋๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค. ํ์ง๋ง state ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ถ์ง ์๋ค๋ฉด ์ค์ฒฉ๋ ์ ๊ฐ ๊ตฌ๋ฌธ๋ณด๋ค ๋ ๊ฐํธํ ๋ฐฉ๋ฒ์ ์ ํธํ ์ ์์ต๋๋ค. Immer๋ ๋ณ์ด ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์์ฑํ๋๋ผ๋ ์๋์ผ๋ก ์ฌ๋ณธ์ ์์ฑํด์ฃผ๋ ํธ๋ฆฌํ ์ธ๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋๋ค. Immer๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑํ๋ ์ฝ๋๊ฐ ๊ท์น์ ๊นจ๊ณ ๊ฐ์ฒด๋ฅผ ๋ณ์ดํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค.
updatePerson(draft => {
draft.artwork.city = 'Lagos';
});
ํ์ง๋ง ์ผ๋ฐ ๋ณ์ด์ ๋ฌ๋ฆฌ ์ด์ state๋ฅผ ๋ฎ์ด์ฐ์ง ์์ต๋๋ค
Immer์์ ์ ๊ณตํ๋ draft๋ ํ๋ก์ํ๋ ํน์ํ ์ ํ์ ๊ฐ์ฒด๋ก ์ฌ์ฉ์๊ฐ ์ํํ๋ ์์ ์ ๊ธฐ๋กํฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ํ๋ ๋งํผ ์์ ๋กญ๊ฒ ์์ ํ ์ ์์ต๋๋ค Immer๋ ๋ด๋ถ์ ์ผ๋ก draft ์ ์ด๋ค ๋ถ๋ถ์ด ๋ณ๊ฒฝ๋์๋์ง ํ์ ํ๊ณ ํธ์ง ๋ด์ฉ์ด ํฌํจ๋ ์์ ํ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
๐ react์์ state ๋ณ์ด๋ฅผ ๊ถ์ฅํ์ง ์๋ ์ด์ ๋?
- ๋๋ฒ๊น : ๋ ๋๋ง ์ฌ์ด์ state๊ฐ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋์๋์ง ๋ช ํํ๊ฒ ํ์ธ์ ์ํด์
- ์ต์ ํ: ๋ณ๊ฒฝ์ด ์์๋์ง ํ์ธํ๋ ๊ฒ์ด ๋งค์ฐ ๋น ๋ฆ
- ์๋ก์ด ๊ธฐ๋ฅ: ๊ณผ๊ฑฐ ๋ฒ์ state๋ฅผ ๋ณ์ดํ๋ ๊ฒฝ์ฐ ์๋ก์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ๋ชปํ ์ ์์
- ์๊ตฌ์ฌํญ ๋ณ๊ฒฝ : ์ฌ์ฌ์ฉ๊ฐ๋ฅ
- ๋ ๊ฐ๋จํ ๊ตฌํ: ๋ณ์ด์ ์์กดํ์ง ์๊ธฐ ๋๋ฌธ์ ํน๋ณํ ์์ ์ด ํ์๊ฐ ์์
'react.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| react ๊ณต์๋ฌธ์๋ก ํ์ตํ๊ธฐ - state๋ก ์ ๋ ฅ์ ๋ฐ์ํ๊ธฐ (0) | 2023.11.30 |
|---|---|
| react ๊ณต์๋ฌธ์ ํ์ต - Responding to Events (0) | 2023.11.29 |
| ํ์ ํฌ๊ธฐ๋ก ์๋ผ ๋จน๋ ๋ฆฌ์กํธ - props (0) | 2023.10.07 |
| ํ์ ํฌ๊ธฐ๋ก ์๋ผ ๋จน๋ ๋ฆฌ์กํธ - State (0) | 2023.10.07 |
| ํ์ ํฌ๊ธฐ๋ก ์๋ผ ๋จน๋ ๋ฆฌ์กํธ- jsx (0) | 2023.10.06 |