์๋ ํ์ธ์ ;) ์น ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ Garden์ ๋๋ค.
์ธํด์ ์์ํ์ง๋ ์ด๋ ๋ง 4๊ฐ์์ด ๋์ด๊ฐ๋ ์์ ์์ ์ง๋ 4์ ํ ๋ฌ์ ํ ์คํธ ์ ๋ฌด์์ ๋ฒ์ด๋ ์ฒ์์ผ๋ก ์ฌ๋ด ์ด์์ฑ ์ ๋ฌด ๋ฅผ ํ๊ฒ ๋์๋๋ฐ์! ์ด๋ ์ฌ๋ด ํ๋ก ํธ์๋ ์ฝ๋๋ฅผ ๊ฐ์ก๊ณ ๊ผผ๊ผผํ๊ฒ ๋ณด๊ฒ ๋์๋๋ฐ ์ด๋ฒ ์ด์์ฑ ์ ๋ฌด๋ค์ ํ๋ฉด์ ์๋์ ๊ฐ์ ์ด์ ๋๋ฌธ์ ๋ฐ์ฑ์ ๋ง์ด ํ๊ฒ ๋์์ต๋๋ค ๐ฅฒ
์๋ํ๋ฉด ์ ๊ฐ ๊ทธ๋์ ์ปดํฌ๋ํธ ์ํ๋ ๊ฑฐ์ ๋๋ถ๋ถ useState๋ก๋ง ๊ตฌํํ์๋ค๋ ์ ์ด์์ต๋๋ค.. ์ฐ์ "์ํ๋ถํฐ ๊ตฌํํ๊ณ ๋ณด์!" ๋ผ๋ ์๊ฐ์ด ์ญ ์ต๊ด์ผ๋ก ์ด์ด์ ธ ๋ ๊ฒ ๊ฐ์์ด์ .. ๊ทธ๋์ useReducer, useRef๋ก ๊ด๋ฆฌ๋๋ ์ฌ๋ด ์ฝ๋๋ฅผ ๋ณด์์ ๋ ๋์ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ ์ด๋ฅผ ์์ฉํด์ useState -> useReducer, useRef๋ก ๋ฆฌํฉํ ๋งํ๋ ๊ณผ์ ์์ ์๊ฐ์ ๋ง์ด ํฌ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์์ ์ด์๋ก ์ ์ง๋ ์๊ฐ์ ๋ฐ์ฑํ๋ฉฐ ์ค๋์ React์์ ์ํ์ ๋ํ ๋ชจ๋ Hooks์ ๋ํด ๋ค์ ๊ณต๋ถํ๊ณ ์ค์ค๋ก ๋๊ตฐ๊ฐ์๊ฒ ์ค๋ช ํ๋ฏ ์ ๋ฆฌํ๋ ์๊ฐ์ ๊ฐ์ ธ๋ณด๊ฒ ์ต๋๋ค!
์ฐ๋ฆฌ๋ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ํ๋ฉด์ ์ํ
๋ฅผ ๊ตฌํํ๋ ๊ฐ๋ฐ flow๊ฐ ์ด๋ป๊ฒ ๋์๋์ง ํ๊ณ ํด๋ด
์๋ค.
์ํ์๋ ์ปดํฌ๋ํธ ์ํ
, ์ ์ญ ์ํ
, ์๋ฒ ์ํ
๊ฐ ๋ํ์ ์ผ๋ก ์๊ณ , ์ด ์ํ๋ค์ ๊ด๋ฆฌํ๋ค๊ฐ ๋ณด๋ ์ํ ๋ณ๊ฒฝ
์ด๋ ์ํ ์ต์ ํ
์ ๊ฐ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ๋ค์ ์๊ฐํ๊ฒ ๋ฉ๋๋ค. ์ด๋ ๋ ๋๋ง์ ๋ฌธ์ ๊ฐ ์๊ธด๋ค๋ฉด ๋ ๋๋ง ์ต์ ํ
๋ฅผ ํด์ผํ๊ณ , ์ด ๊ณผ์ ์์ ๋์ค๋ ์ํ ๊ด๋ฆฌ์
๋ค์ ๋ฐฐ์ฐ๊ณ .. ์ด๋ฐ ์ผ๋ค์ด ์ง์์ ์ผ๋ก ๋ฐ๋ณต๋๊ณ ์์ต๋๋ค...
๊ฒฐ๋ก ์ ์ผ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ๋ฉด์ ์ด๋ ์๊ธฐ๋ ๋ ๋๋ง ๋๋ฌธ์ ๊ณ์ ์ต์ ํ ํด๋์๊ฐ๋ ๊ณผ์ ์์ ์ ์ํ๊ด๋ฆฌ๋ฅผ ํ๊ณ ์์ง ๋ผ๋ ์๋ฌธ์ด ๋ค๊ฒ ๋์์ต๋๋ค
๊ทผ๋ณธ์ ์ผ๋ก ์ํ๋ ๋ฌด์์ธ์ง ์๊ฐํด๋ณด๊ณ ์ถ์ต๋๋ค. ์ํ๋ ๋ฌด์ธ๊ฐ์ ๋ชจ์์ด๋ ํํธ์ ๋ปํด์! ์์๋ฅผ ๋ค์๋ฉด Garden์ ์ค๋ ํ๋ณตํ ์ํ์ผ ;)
or ์ด๋ฏธ ์์ญ๋ฆฌ์ญ์๋ ๋ง์ฐจ๊ฐ ๋๊ธด ์ํ
๊ฐ ๋ ์ ์๊ฒ ๋ค์
๊ทธ๋ผ ๊ฐ๋ฐ์์์ ์ํ๋ ์ด๋ค ๊ฒ ๋ ์ ์์๊น์?
export const ButtonStyles: CssArchiveType = {
default: css`
display: flex;
align-items: center;
justify-content: center;
border-radius: 12px;
border: none;
cursor: pointer;
background-color: ${Colors.Primary};
color: ${Colors.White};
`,
`,
...
}
์์ ์คํ์ผ ์ฝ๋๋ฅผ ๋ด๋ ์ ์ ์๋ฏ์ด, ์ผ์ชฝ์ ์ํ์ ๋ค์ด๋ฐ์ด๋ ํ๋๋ฅผ ํ๊ธฐํ๊ณ ์๊ณ , ์ค๋ฅธ์ชฝ์๋ ๊ทธ๋์ ์ํ๋ฅผ ์์ฑํด์ฃผ๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋๊น
background-color: ${Colors.Primary}
๋ฅผ ๋ณด๋ฉด ๋ฐฐ๊ฒฝ์์ ${Colors.Primary} ์ํ๋ก ์ง์ ํด ๋ผ๋ ์๋ฏธ๋ก ๋ณผ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ๊ฐ๋ฐ์ ํ๊ธฐ ์ ์ "์ด๋ ๋ถ๋ถ์์ ์ํ๊ฐ ํ์ํ๊ณ ์ด๋ค ์ํ๊ฐ ํ์ํ ์ง" ์๊ฐํด๋ณด๋ ๊ณผ์ ์ ๊ฐ๋ฐ ์ค๊ณ์ ๋ค์ด๊ฐ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
์ ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ํ์ ์ฌ๋ฐ๋ฅธ ์ด๊ธฐ๊ฐ์ ์ค์ ํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ์ด๊ธฐ ๊ฐ
์ด๋, ๋ฆฌ์กํธ์์ ํ๋์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋๋ฐ ์ฌ๋ฌ ์ผ์ด ๋ฐ์ํ๊ณ , ๋ด๊ฐ ์๊ฐํ ๋๋ก ๋์ํ์ง ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
์ฝ๋๋ก ์ดํด๋ณด์๋ฉด,
function getData () {
const [data, setData] = useState();
useEffect (() => {
const fetchData = async () => {
const response = await fetch("https://api.example.com");
const result = await response.json();
setData(result);
};
fetchData();
}, []);
return (
{data.map((item) => (
~~
}
);
}
์์ ์ด๊ธฐ ๊ฐ ์ ์ธ์์๋ useState์์ ์๋ฌด๊ฒ๋ ์์ผ๋ฏ๋ก ์๋ฌด ๊ฐ๋ ์ค์ ๋์ด์์ง ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ fetchData๋ผ๋ ํจ์๊ฐ ์คํ์ด ๋๋ฉด ๊ทธ์ ์์ผ setData๊ฐ ๋๋ฉด์ data์์ ๊ฐ์ด ๋ค์ด๊ฐ๊ฒ๋ฉ๋๋ค.
return๋ฌธ ์์์ data๋ฅผ ์ ๋ฐ์์ ๋ฃ์ผ๋ฉด ์ ์คํ๋๋ค๊ณ ๋ณผ ์ ์๊ธฐ๋ ํ๊ฒ ์ง๋ง
๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ๋ ๋๋งํ๋๋ฐ ๋ฐ์ดํฐ๊ฐ ์์ด์ .map()์ array์ ํ๋กํ ํ์
์์ ๊ฐ์ ธ์ค๋ ์๊ฐ์ ์ฐจ์ด ๋๋ฌธ์ ๋ ๋๋ง ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ์
๋๋ค.
๋ฐ๋ผ์ ๋ฌด์๋ฏธํ ์ฝ๋๊ฐ ๋ค์ด๊ฐ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด์, array๊ฐ ๋ง๋์ง data๋ฅผ ๋จผ์ ํ์ธํด์ผํ๋ ์ฝ๋๊ฐ ์ ์ธ๋์ด์ผํฉ๋๋ค. ์๋์ ๊ฐ์ด ๊ณ ์ณ๋ณผ ์ ์๊ฒ ๋ค์!
{Array.isArray(data) && data.map((item) => (
~~
}
๊ทธ๋ฐ๋ฐ ์ด ๋ฐฉ๋ฒ์ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค. ์์ ์์๋ ์ด๊ธฐ ๊ฐ์ด ์์๊ธฐ ๋๋ฌธ์ ์์ฑํด์ค์ผํ๋ ์ฝ๋์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ฐ๋ฆฌ๋ ์์ ๊ฐ์ ์ํฉ์์ ์ด๊ธฐ ๊ฐ์ ์ค์ ํ ๋ ๋ฐฐ์ด์ ๋ฃ์ด ๋ค์๊ณผ ๊ฐ์ด ์ด๊ธฐ ๊ฐ์ ํ ๋นํด์ค ์ ์์ต๋๋ค.
const [data, setData] = useState([]);
๋ฆฌ์กํธ ๋ ๋๋ง์ ์ฐ๋ฆฌ๊ฐ ์๊ฐํ๋ ๊ฒ๊ณผ ๋ค๋ฅด๊ฒ ์ฌ๋ฌ ๋ฒ ๋ฐ์๋๊ณ ์๋๊ฐ, ์์๊ฐ ์ ๊ฐ๊ฐ์ด๊ธฐ์ ์ด๊ธฐ ๊ฐ์ด ์ ๋ง ์ค์ํ๋ค๋ ๊ฒ์ ๊นจ๋ซ๊ฒ ๋์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ useState๋ฅผ ๋น์๋๊ฒ ๋๋ค๋ฉด ๊ทธ ๋ณ์์ ๋ค์ด๊ฐ๋ ๊ฐ์ undefined
๊ฐ ๋๋ ํญ์ ์ด๊ธฐ๊ฐ ์ค์ ์ ์ฃผ์ํ๋๋ก ํฉ์๋ค.
๋ฐ๋ผ์ ์ด ์ง๋ฌธ์ ์์์ธ ์ด๊ธฐ ๊ฐ์ด๋,
- ๊ฐ์ฅ ๋จผ์ ๋ ๋๋ง ๋ ๋ ์๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ง ์ ์๋ ๊ฐ
- ์ด๊ธฐ์ ๋ ๋๋ง ๋๋ ๊ฐ
์ผ๋ก ์ ๋ฆฌํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๋ฅผ ์งํค์ง ์๋๋ค๋ฉด? -> ๋ ๋๋ง ์ด์, ๋ฌดํ ๋ฃจํ, ํ์ ๋ถ์ผ์น๋ก ์๋์น ์์ ๋์ -> ๋ฐํ์ ์๋ฌ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
๋ํ ์ด๊ธฐ๊ฐ ์ ์ค์ ํด์ค๋ค๋ฉด ๋น๊ฐ์ด๋ null ์ฒ๋ฆฌ๋ฅผ ํ ๋ ๋ถํ์ํ ๋ฐฉ์ด์ฝ๋๋ ์ค์ฌ ๋ ์์ ํ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฐํ ์ ์์ ๊ฒ์ ๋๋ค.
์ด๋ฒ์๋ ๋ณ์๋ฅผ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ๋ด๋ถ์ ์ง์ ์ ์ผ๋ก ๊ฐ์ง๊ณ ์์ ๋์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.
function NotUpdataValue() : Element {
const INFO = {
name: 'My Component',
value: 'Clean Code React',
const [ count, setCount] = useState(0);
return(
<div className = "App">
<header>{INFO}</header> // child
<ShowCount info={INFO} count={count} /> //props
</div>
);
}
์์ ํจ์ ์ ์ธ๋ถ๋ฅผ ๋ณด๋ฉด INFO๋ผ๋ ๊ฐ์ฒด๊ฐ ์ ์ธ๋์ด ์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ๋ ์์๋ฅผ ๋ค๋ฃจ๊ฑฐ๋, ์ผ๋ฐ์ ์ธ ๋ฐฉ์น๊ฐ ๊ฐ์ฅ ํํ ๊ฒฝ์ฐ์ ๋๋ค. ์ด ๊ฐ์ฒด๋ ํ์ฌ return๋ฌธ ์ ์ ์ด๋ค ๋ถ๋ถ์์๋ ์ฌ์ฉ๋๊ณ ์์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ฆ ์ด ๊ฐ์ฒด์ ์๋ ์์ฑ์ ๋ฐ๊พธ๋ ๊ฒฝ์ฐ๊ฐ ์ ํ ์์ง ์์ต๋๋ค.
์ฆ INFO ๊ฐ์ฒด๋ ํ์ฌ ์
๋ฐ์ดํธ๊ฐ ๋์ง ์๋ ์ผ๋ฐ์ ์ธ ๊ฐ์ฒด
๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค. ํ์ง๋ง return ๋ฌธ ์์์ ๋ณด๋ฉด header์์๋ child๋ก, ShowCount์์๋ ํ๋์ props๋ก ๊ฐ์ฒด๋ฅผ ๋ด๋ฆฌ๊ณ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ๋ ๋ถ์ ์ ํ ๊ฒฝ์ฐ์ธ๋ฐ, ๊ทธ ์ด์ ๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ๋ด๋ถ์ ์๋ ์ ๋ค์ธ๋ฐ ๋งค๋ฒ ๋ ๋๋ง์ด ๋ ๋๋ง๋ค ๊ฐ์ ๊ฐ์ด๋๋ผ๋ ๋ถํ์ํ๊ฒ ์ฐธ์กฐํ๊ณ ์๋ ์ํ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
์์ ๊ฒฝ์ฐ๋ 2๊ฐ์ง ๊ฒฝ์ฐ๋ก ๋ฆฌํฉํ ๋ง์ ํ ์ ์๋๋ฐ ๋ฐ๋ก ๋ฆฌ์กํธ ์ํ๋ก ๋ณํ
or ์ธ๋ถ๋ก ๋ด๋ณด๋ด๊ธฐ
์ ๋ฐฉ๋ฒ์ ๊ณ ์ํ ์ ์์ต๋๋ค. ์์ ์ปดํฌ๋ํธ ์ธ๋ถ๋ก ๋นผ๋ ๊ฒ์ด ์ข์ต๋๋ค :)
const INFO = {
name: 'My Component',
value: 'Clean Code React',
}
function NotUpdataValue() : Element {
const [ count, setCount] = useState(0);
return(
<div className = "App">
<header>{INFO}</header> // child
<ShowCount info={INFO} count={count} /> //props
</div>
);
}
์ด์ ๋ ์ด๊ธฐ๊ฐ์ ๋ฐ๊ฟ์ผํ๋ ๊ฒฝ์ฐ๋ ๊ฐ์ด ๋ณํ๋ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
const Mock_data = [
{
userId: 1,
id: 1,
title: 'clean code',
completed: false
},
{
userId: 2,
id: 2,
title: 'funny code',
completed: true
},
...
]
function NotUnessState() {
const [userList, setUserList] = useState(Mock_data) //์ด๊ธฐ ์ํ ์ ์ธ
const [complUserList, setComplUserList] = useState(Mock_data) //๋ณ๊ฒฝ ํ ์ ์ฅํ ์ํ ์ ์ธ
}
์์ ๊ฐ์ด ์๋ฃํ ์ผ๋ง ๊ฐ์ง๊ณ ์๋ ์ ์ ๋ฆฌ์คํธ๋ฅผ ์์ฑํด๋ณด์์ต๋๋ค. Mock_data
์์ completed๊ฐ true์ธ ํญ๋ชฉ๋ค๋ง list๋ก ๋ฐ๊พธ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
const [complUserList, setComplUserList] = useState(Mock_data)
useEffect((): void => {
const newList = complUserList.filter(user) : boolean => user.completed === true);
setUserList(newList);
},[userList];
์ด๋ ๊ฒ ์กฐ๊ฑด์ ์ค์ ํด ์์ฑํด๋ณด์๋๋ฐ ์ด๊ฒ๋ ๋นํจ์จ์ ์ธ ์ฝ๋๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
์์ ์ฝ๋๋ฅผ useEffect() ๋ฐ์ผ๋ก ๋นผ์ ๋ด๋ถ์ ๋ณ์๋ก ์ ์ธํ๊ฒ ํ๋ฉด ๋ฉ๋๋ค.
const complUserList = complUserList.filter(user) : boolean => user.completed === true);
๋ ๋๋ง ๋ ๋๋ง๋ค ๊ฐ์ด ๋ฐ๋๊ณ ๊ด์ฌ๋์ง๋ง ์ด ๊ฐ์ ๊ตณ์ด ์ํ๋ก ๋ง๋ค ํ์๊ฐ ์๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค.
๊ฒฐ๊ตญ ๋ ๋๋ง ์ ๊ณ ์ ์ complUserList ๊ฐ ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๊ด๋ฆฌํ ํ์๋ ์๊ณ setํ ํ์๋ ์๊ฒ ๋ฉ๋๋ค.
์ ๋ ์ด๋ ์ปดํฌ๋ํธ ๋ด๋ถ์ ์ ์ธ๋ ๋ณ์๋ฅผ ์ด๋ค ์ญํ ์ ํ๋์ง ๊ถ๊ธํ๋๋ฐ์,
์ปดํฌ๋ํธ ๋ด๋ถ์์์ ๋ณ์๋ ๋ ๋๋ง ๋ง๋ค ๊ณ ์ ์ ๊ฐ์ ๊ฐ์ง๋ ๊ณ์ฐ๋ ๊ฐ์ ๊ฐ์ง๋ค๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ๋ถํ์ํ ์ํ๋ฅผ ๋ง๋ ๋ค๋ฉด?
๊ฒฐ๊ตญ์๋ ๋ฆฌ์กํธ์ ์ํด ๊ด๋ฆฌ๋๋ ๊ฐ์ด ๋์ด๋๋ ๊ฒ์ด๊ณ ,
๊ทธ๋ฌ๋ค๋ณด๋ฉด ๋ ๋๋ง์ ์ํฅ์ ์ฃผ๋ ๊ฐ์ด ๋์ด๋์ ๊ด๋ฆฌ ํฌ์ธํธ๊ฐ ๋๋์ฑ ๋์ด๋๊ฒ ๋ฉ๋๋ค.
์ปดํฌ๋ํธ์ ์ ์ฒด์ ์ธ ์๋ช ๊ณผ ๋์ผํ๊ฒ ์ง์๋ ์ ๋ณด๋ฅผ ์ผ๊ด์ ์ผ๋ก ์ ๊ณตํด์ผํ๋ ๊ฒฝ์ฐ์๋ useState ๋์ ์ useRef๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์๋ ์๋๋ฐ์! ๊ฒฐ๊ตญ ๋ฆฌ๋ ๋๋ง ๋ฐฉ์ง๊ฐ ํ์ํ ๋ useRef๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
useState๋ฅผ ํตํด ๊ฐ์ด ๋ง๋ค์ด์ง๋ฉด setState๊ฐ ๋์์ ํ๋ฉด์ ์ํ์ง ์๋ ๋ฆฌ๋ ๋๊ฐ ์ปดํฌ๋ํธ์ ๋ฐ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ฆฌ๋ ๋๊ฐ ๋์ง ์๊ณ ์ด๊ธฐ๊ฐ์ ๋ํ๋ด๊ฑฐ๋ ๋ฆฌ๋ ๋๊ฐ ๊ตณ์ด ๋์ง ์๊ณ ๋ ๋๋ง ํ๋ก์ธ์ค์ ๊ด๊ณ์์ด ๊ฐ์ ๊ฐ๋ณ์ ์ผ๋ก ์ ์ฅํ๊ณ ์ถ์ ๊ฒฝ์ฐ ๊ทธ๋๋ useRef๋ฅผ ๊ณ ๋ คํ๋๊ฒ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋จผ์ useState๋ก ์ฌ์ฉ์์ ์ ๋ ฅ์ ์ถ์ ํ๊ณ ํ๋ฉด์ ํ์ํ๋ ์ปดํฌ๋ํธ ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
import { useState } from 'react';
function InputComponent() {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<input type="text" value={inputValue} onChange={handleChange} />
<p>์
๋ ฅ๊ฐ: {inputValue}</p>
</div>
);
}
export default InputComponent;
์์ ์ฝ๋์์๋ inputValue
์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๊ณ , ์ฌ์ฉ์๊ฐ ์
๋ ฅ ํ๋์ ๋ฌธ์๋ฅผ ์
๋ ฅํ ๋๋ง๋ค setInputValue
ํจ์๊ฐ ํธ์ถ๋์ด ์ํ๊ฐ ๊ฐฑ์ ๋๊ณ , ์ด๋ก ์ธํด ์ปดํฌ๋ํธ๊ฐ ์๋ก ๋ ๋๋ง ๋ฉ๋๋ค.
์ด์ ๋ useRef๋ฅผ ์ฌ์ฉํด์ ๋ฆฌ๋ ๋๋ง์ ์ ๋ฐํ์ง ์์ผ๋ฉด์ ๊ฐ์ด ์ ์ง๋๋ ref๊ฐ์ฒด๋ฅผ ๋ฐํํด ์ํ์ ๋ณ๊ฒฝ์ ์ถ์ฒํ๋ฉด์ ์ปดํฌ๋ํธ์ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
import { useRef } from 'react';
function InputComponentWithRef() {
const inputValueRef = useRef('');
const handleChange = (event) => {
inputValueRef.current = event.target.value;
console.log(`์
๋ ฅ๊ฐ: ${inputValueRef.current}`);
};
return (
<div>
<input type="text" onChange={handleChange} />
</div>
);
}
export default InputComponentWithRef;
์์ ์ฝ๋์์๋ inputValueRef
๋ฅผ ์ฌ์ฉํ์ฌ ์
๋ ฅ๊ฐ์ ์ถ์ ํ๊ณ ์์ต๋๋ค. ๊ฒ๋ค๊ฐ useRef๋ ์ปดํฌ๋ํธ์ ๋ฆฌ๋ ๋๋ง์ ๋ฐ์์ํค์ง ์์ผ๋ฏ๋ก handleChange
ํจ์ ๋ด์์ ์
๋ ฅ๊ฐ์ด ๊ฐฑ์ ๋์ด๋ ํ๋ฉด์ด ์๋ก ๋ ๋๋ง ๋์ง ์์ต๋๋ค. ๊ผญ DOM์ ๋ถ์ฌ์ ์ฐ๋ ๊ฒ๋ง์ด ref ์ฌ์ฉ์ ๋ค๋ ์๋๋ค๋ผ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ฌ๋ฌ ์ํ๋ค ์ค์์ ๊ตฌ์กฐํ๋ ์ํ๋ฅผ ์ํ๋ฉด useReducer๋ฅผ ์ฌ์ฉํด๋ณด๋ ๊ฑธ ๊ณ ๋ คํ ์ ์์ต๋๋ค.
์ ๋ useReducer๋ฅผ ์ฒ์ ๋ดค์ ๋ ๋ฆฌ๋์ค๋ ๋น์ทํ๋ค๋ ์๊ฐ์ ํ์๋๋ฐ์, ์๊ณ ๋ณด๋ ๋ฌธ๋ฒ์ด ์ ์ฌํ๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค ํํ ์ฝ๋๋ก ํ ๋ฒ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
const INIT_STATE = {
isLoading: false,
isSuccess: false,
isFail: false,
}
function StateToReducer(){
const [state, dispatch]= useReducer(reducer, INIT_STATE)
์ฌ๊ธฐ์ ์ ๊น reducer ์์ฑ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๋ฉด, ๋จผ์ useReducer()์ด๋ผ๋ ํจ์๋ฅผ ๋จผ์ ๊ฐ์ ธ์ค๊ณ
๋ง์ฐฌ๊ฐ์ง๊ณ ๋ฐฐ์ด ๊ตฌ์กฐ ๋ถํด ํ ๋นํด์ ๊ฐ์ ธ์ต๋๋ค. ์์ ์ฝ๋์์ state๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ด ์ํ๋ฅผ setํ๋ dispatch๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
์ฒซ ๋ฒ์งธ ์ธ์๋ก๋ reducer๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ด๋ ์กฐ์ํ๋ ํจ์๊ฐ ๋ฉ๋๋ค. ๋ ๋ฒ์งธ ์ธ์์๋ ์ด๊ธฐ๊ฐ์ ๋ฃ์ ์ ์๋ค๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
์ฌ๊ธฐ์ reducer callback์ผ๋ก ํ์ฌ ์ํ์ ์ด ์ํ๋ฅผ ๋ณํํ ์ ์๋ ์ก์ ์ ๋ฐ๋ reducer๋ฅผ ์ ์ธํด๋ณด๊ฒ ์ต๋๋ค.
...
const reducer = (state, action) =>{
switch (action.type){
case 'FETCH_LOADING':
return { isLoading: true, isSuccess: false, isFail: false}
case 'FETCH_SUCCESS':
return { isLoading: false, isSuccess: true, isFail: false}
case 'FETCH_FAIL':
return { isLoading: false, isSuccess: false, isFail: true}
defalt:
return INIT_STATE
}
function StateToReducer(){
const [state, dispatch]= useReducer(reducer, INIT_STATE)
๋จผ์ ํด๋น ์ก์ ์ type์ ๋ฐ์ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ swich ๋ฌธ์ผ๋ก ๊ฐ๊ฐ์ ์กฐ๊ฑด์ ๋ง๊ฒ ๋ฐ๋ ๊ฐ์ ์ง์ ๋ช ์ํด์ค๋๋ค.
๊ทธ ๋ค์์ ํจ์ ๋ด๋ถ์์ dispatch๋ฅผ ํธ์ถํ๊ณ , ํ์ ์ ์ฐ๋ฆฌ๊ฐ ์ ์ํ๊ฒ์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
...
function StateToReducer(){
const [state, dispatch]= useReducer(reducer, INIT_STATE)
const fetchData = () => {
dispatch({ type: 'FETCH_LOADING'})
... ๋์ผํ๊ฒ ใฑใฑ
์ด๋ ๊ฒ ๋ฆฌํฉํ ๋งํ๋ฉด ์ํ๋ฅผ ์ธ๋ฐํ๊ฒ ์์ฑํ ์ ์๊ณ , reducer ํจ์๋ฅผ ์์ฑํ ๋ถ๋ถ์ ์์ํ js ๋ฌธ๋ฒ์ด๊ธฐ ๋๋ฌธ์ react์ ์์กด์ ์ธ ์ฝ๋๊ฐ ์๋๋๋ค.
useReducer๋ ์ํ๋ฅผ ํ๋ํ๋ ์กฐ์ํ๊ณ , ๋ก์ง์ด ์ฝํ์๋ ๋ถ๋ถ์ ๋ค ์ถ์ํ ํด์ค๋๋ค. action type๋ง ํธ์ถํ๋ฉด ๊ทธ ์์ ๋ด๋ถ ๋ก์ง์ด ๋ชจ๋ ์ถ์ํ ๋์ด์๊ธฐ ๋๋ฌธ์ ํจ์๋ฅผ ํธ์ถํ๋ ๊ตฌ๋ฌธ์์๋ ๋ด๋ถ์ ๋ญ๊ฐ ์๋์ง ๋ชฐ๋ผ๋ action type๋ง ๋ณด๊ณ ๋ ์ถ์ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ํญ์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฐํ ๋, ํ๋ฉด์ ๋ ๋๋ง ๋๋ ์ฝ๋๋ง ๋จ๊ธฐ๊ณ , ๋ก์ง์ ๊ด๋ จ๋ ๋ถ๋ถ๋ง ๋นผ๋ณด๋ ๋ฆฌํฉํ ๋ง์ด ์ค์ํ๋ฐ์! ์ด๋ custom hook์ ์ฌ์ฉํด ๊ตฌํํ ์ ์์ต๋๋ค.
๊ฐ๋จํ ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ ์ํ๋ก์ง์ด ๊ตฌํ๋ ์์ ์ฝ๋๋ก ๋จผ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
import { useState } from 'react';
function useInputHooks(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = (event) => {
setValue(event.target.value);
};
return [value, handleChange];
}
์ฌ๊ธฐ์ useInputHooks์ด๋ผ๋ ์ปค์คํ ํ ์ ๋ง๋ค์ด ์ ๋ ฅ ๊ฐ์ ๊ด๋ฆฌํ๊ณ , ์ด ์ ๋ ฅ ๊ฐ์ ๋ณ๊ฒฝํ๋ ํจ์์ ์ ๋ ฅ๊ฐ์ ๋ฐํํ๋๋ก ์ฝ๋๋ฅผ ๊ตฌํํ์ต๋๋ค.
import React from 'react';
import useInputHooks from './hooks/useInputHooks';
function InputComponent() {
const [inputValue, handleInputChange] = useInput('');
return (
<div>
<input type="text" value={inputValue} onChange={handleInputChange} />
<p>์
๋ ฅ๊ฐ: {inputValue}</p>
</div>
);
}
export default InputComponent;
์์ ์ฝ๋์์๋ ์์์ ๋ง๋ useInputHooks๋ฅผ ์ฌ์ฉํด์ ์ฌ์ฉ์์ ์ ๋ ฅ ํ๋์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์ปดํฌ๋ํธ ์ฝ๋์ ๋๋ค. useInputHooks๋ฅผ ์ด ์ปดํฌ๋ํธ ๋ฟ๋ง์๋๋ผ ๋ค๋ฅธ ์ปดํฌ๋ํธ์์๋ ์ฌ์ฉํ ์ ์๊ธฐ๋๋ฌธ์ ์ฝ๋๋ฅผ ํ์ฅ์ฑ์๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒ ์์ฑํ ์ ์๊ฒ ๋ฉ๋๋ค!
์ค๋ ์ด ํฌ์คํ
์ ์์ฑํ๋ฉด์ "๋น์ฐํ๊ฒ ์์ฑํ๋ ๊ฒ๋ค" ์ ๋ํด์ ๋ผ์ด๋ธ ์ฝ๋ฉ์ ํด๋ณด๋ฉด์ ์ต๊ด์ ์์กด์ฑ์ ๋ฐ์ฑ์ ํ๊ฒ ๋์์ต๋๋ค. ๋ํ ๋ง๋ก ์ค๋ช
ํ๋ค๋ณด๋ ์ ๊ฐ ๋ชฐ๋๋ ๋ถ๋ถ์ ๋ํด์ ์ ํํ ์ง๊ณ ๊ฐ์ ์์๊ณ
ํนํ reducer ๋ถ๋ถ์ด ํ์ฌ์์๋ ์ดํดํ๊ธฐ ์ค๋ ๊ฑธ๋ ธ๋๋ฐ ๋ฌธ๋ฒ ์ฑ
์ ๋ณด๊ณ ํ๋ํ๋ ์ง์ ์ฉ ์ฝ๋ฉ์ ํด๋ณด๋๊น ๋์์๋ฆฌ๋ฅผ ์์๊ฐ๊ฒ ๋ ์ ์์๋ ์๊ฐ์ด์์ต๋๋ค.
์ด์ ๋ถํฐ๋ ๋๋ถ๋ถ useState()์ ์ต์ํ๋ ์๊ฐ์ ์กธ์
ํ๊ณ ์ข ๋ ๋์ hooks ๋ค๋ก ํด๋ฆฐ์ฝ๋๋ฅผ ์ง๋ ์ฐ์ต์ ํ๋๊ฒ ์ค์ํ ๊ฒ ๊ฐ์ต๋๋ค ๐ฅ ๐ฅ