React_useReducer ์ํ๊ด๋ฆฌ
๐ค ์ ๊ฐ useReducer ํ
์ ์ดํดํ๊ธฐ ์ํด ์์ฑํ ๊ธ ์๋๋ค,,
useReducer
๊ณต์ ๋ฌธ์๋ฅผ ํ์ธํ๋ฉด โuseReducer์ ์ปดํฌ๋ํธ์ reducer์ ์ถ๊ฐํ๋ ๋ฆฌ์กํธ์ ํ
โ ์ด๋ ๊ฒ ์ ์ํ๊ณ ์๋ค.
useReducer๋ฅผ ์ฌ์ฉํ๋ ๋ชฉ์ ์ ์๋ก ๊ด๋ จ์ด ์๋ ์ฌ๋ฌ ์ํ๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ๋ฌถ๊ณ , ํ๋์ ํจ์(reducer) ์์์ ์ด๋ป๊ฒ ๋ฐ๋์ง๋ฅผ ์ ๋ฆฌํด ์ํ ์
๋ฐ์ดํธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด์์ด๋ค.
๊ฐ์์์ useState์์ useReducer ๋ชจ๋ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ํ
์ ๋ณ๊ฒฝํ๋๋ฐ ๊ทธ๋ ๋ค๋ฉด ์ธ์ useState๋ฅผ ์ฐ๊ณ , ์ธ์ useReducer๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ๋์ง ๊ธฐ์ค์ด ์ด๋ป๊ฒ ๋ ๊น ๊ถ๊ธํ๋ค.
useState, useReducer ์ฌ์ฉ ๊ธฐ์ค
๋จผ์ useState์ useReducer ๋์ผํ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ ์ธ์ ๋ ๋ง์๋๋ก ๋ฐ๊ฟ์ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ๋ฉฐ ๊ฐ์ ์ปดํฌ๋ํธ ์์์ ์์ด์๋ ์ฌ์ฉํ ์ ์๋ค๊ณ ํ๋ค.
| ๊ธฐ์ค | useReducer | useState |
|---|---|---|
| ์ํ ์ | ์ํ๊ฐ ์ฌ๋ฌ๊ฐ์ด๊ณ ๋ณต์กํ ๋ | ์ํ๊ฐ 1~2๊ฐ๋ก ๋จ์ํ ๋ |
| ์ํ ๊ฐ ๊ด๊ณ | ์ํ ๊ฐ๋ค์ด ์๋ก ์ํฅ์ ์ฃผ๊ณ ๋ฐ๊ฑฐ๋, ํ ์ก์ ์ด ์ฌ๋ฌ ์ํ๋ฅผ ๋์์ ๋ฐ๊ฟ์ผ ํ ๋ |
๊ฐ ์ํ๊ฐ ๋ ๋ฆฝ์ ์ผ ๋ |
์ข ๋ ๋ณต์กํ ์ํ์ด๊ฑฐ๋ ์ฌ๋ฌ ์ํ๋ค๋ผ๋ฆฌ ์ฐ๊ด ๋์ด์์ ๋ setState๋ฅผ ์ฌ๋ฌ ๋ฒ ๋๋ ์ ํธ์ถํ๋ ๊ฒ๋ณด๋ค useReducer๋ก ๋ฌถ์ด์ ๊ด๋ฆฌํ๋ ๊ฒ ๋ ๊น๋ํ๊ณ ์ ์ง ๋ณด์๊ฐ ์ฝ๋ค๋ ์ฅ์ ์ด ์์ด ์ํฉ์ ๋ฐ๋ผ ์ ํํด ์ฌ์ฉํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๐ useState ์ useReducer ๋น๊ตํ๊ธฐ
๐คย ๊ทธ๋ฐ๋ฐ ์ปดํฌ๋ํธ์ reducer์ ์ถ๊ฐํ๋ค๋ ๊ฒ ๋ฌด์จ ๋ง์ธ์ง ์๋ฟ์ง ์์๋ค.
useReducer ์์์ reducer ๋?
reducer๋ ํ์ฌ ์ํ(state)์ ์ก์
(action)์ ์ธ์๋ก ๋ฐ์ ์๋ก์ด ์ํ๋ฅผ ๋ฐํํ๋ค.
์ํ๋ฅผ ์ด๋ป๊ฒ ๋ฐ๊ฟ์ผ ํ ์ง๋ฅผ ์ ์ํด๋๊ณ action์ด ๋ฐ์ํ์ ๋ ํด๋น action์ ์คํํด ์๋ก์ด ์ํ๋ฅผ ๋ฆฌํดํ๋ ํจ์๋ผ๊ณ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๋ฆฌ์กํธ๋ reducer๊ฐ ๋ฐํํ ์ ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ state ๊ฐ์ ์ค์ ํ๊ณ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ ๋๋ง ํ๋ค.
import { useReducer } from "react";
//ํด๋น ํจ์๊ฐ ์คํ๋ ๋๋ง๋ค ์ปดํฌ๋ํธ ์์ ํจ์๋ค์ด ์ฌ์์ฑ๋๋๋ก ํ์ง ์๊ธฐ ์ํด์ ์ปดํฌ๋ํธ ๋ฐ์ ์์ฑํ๋ค.
//reducer๋ state, action๋ง ์ธ์๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ ์ปดํฌ๋ํธ ํจ์ ์์์ ์ ์๋๊ฑฐ๋ ์
๋ฐ์ดํธ๋๋ ์ด๋ค ๊ฐ์๋ ์ง์ ์ ๊ทผํ ํ์๊ฐ ์๋ค.
function reducer(state, action) {
//state: useReducer๋ก ๊ด๋ฆฌ๋๋ ์ํ์ ๋ณด์ฅ๋ ์ต์ ์ํ ์ค๋
์ท
// ...
}
action : ์ฌ์ฉ์๊ฐ ์ด๋ค ํ๋์ ํ๋์ง๋ฅผ ๋ํ๋ด๋ ๊ฐ์ผ๋ก ๋ชจ๋ ํ์
์ด ๋ ์ ์์ง๋ง ๋ณดํต ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ
์๋ฅผ ๋ค์ด ๋ํ๊ธฐ ๋ฒํผ ํด๋ฆญ โ โ์ซ์์ 1 ๋ํด์ค, ๋นผ๊ธฐ ๋ฒํผ ํด๋ฆญ โ โ์ซ์์ 1 ๋นผ์คโ
//์ผ๋ฐ์ ์ธ action์ ๊ตฌ์ฑ
{
type: "increment", // ์ด๋ค ํ๋์ธ์ง ์๋ ค์ฃผ๋ ๋ฌธ์์ด
payload: 2, // ์ถ๊ฐ ๋ฐ์ดํฐ (์ต์
)
}
payload ์ธ์ ์ฌ์ฉํด์ผํ ๊น?
action์ ์ฒ๋ฆฌํ ๋, ๊ฐ์ด ํ์ํ ๊ฒฝ์ฐ payload๋ฅผ ์ฌ์ฉํ๋ค.
์๋ฅผ ๋ค์ด ํ ์ผ์ ์ถ๊ฐํ๋ค๋ฉด ์๋ก์ด ๋ฐฐ์ด์ ๊ฐ์ ์ถ๊ฐํ ๋ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ์ด ํ์ํ ๋
function reducer(state, action) {
if (action.type === "ADD_TODO") {
return {
...state,
todos: [...state.todos, action.payload],
};
}
//...
}
dispatch({
type: "ADD_TODO",
payload: { id: 1, text: "ํ ์ผ ์ถ๊ฐํ๊ธฐ" },
});
reducer ๋ฅผ ์์ฑํ ๋ ์ง์ผ์ผ ํ๋ ๊ท์น
- ์ค์ง state์ action ์๋ง ์์กดํ๊ณ , โ์ํ๋ฅผ ์ด๋ป๊ฒ ๋ฐ๊ฟ์งโ ๋ง ์ ์ํด์ผ ํ๋ค.
- reducer๋ ๋ถ๋ณ์ฑ์ ์ง์ผ ๊ฐ์ฒด/๋ฐฐ์ด์ ์์ ํด์ผ ํ๋ค.
- reducer๋ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ๊ฑฐ๋ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋๋ก ์ปดํฌ๋ํธ ์ธ๋ถ๋ก ๋ถ๋ฆฌ ๊ฐ๋ฅํ ์์ ํจ์์ฌ์ผ ํ๋ค (reducer ํจ์ ์์์ props, ref, useState, useEffect ์ ๊ฐ์ ์ปดํฌ๋ํธ ์์ชฝ์ ๊ฒ๋ค์ ์ฌ์ฉํ๋ฉด ์ ๋๋ค)
- ๊ฐ action์ ๋ฐ์ดํฐ ์์์ ์ฌ๋ฌ ๋ณ๊ฒฝ๋ค์ด ์๋๋ผ๋ ํ๋์ ์ฌ์ฉ์ ์ํธ์์ฉ์ ์ค๋ช
ํด์ผ ํ๋ค.
(์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ํ ์ผ ์ถ๊ฐํ๊ธฐ ๋ผ๋ ๋ฒํผ์ ํด๋ฆญํ๋ฉด โ todos ๋ฐฐ์ด์ ์๋ก์ด todo ์ถ๊ฐ, input๊ฐ ์ด๊ธฐํ, input focus ์ด๋ ๊ฒ ๋ณ๊ฒฝ๋๋ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ฌ๊ฐ์ฌ๋ ํ๋์ ์ก์ ์ผ๋ก ๋ฌถ์ด์ ์ฒ๋ฆฌ)
* ์์ ํจ์(Pure Function) : ๊ฐ์ ์
๋ ฅ์ ์ฃผ๋ฉด ํญ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๊ณ (์์ธก์ด ๊ฐ๋ฅํ๊ณ ), ์ธ๋ถ ์ํ๋ sideEffect์ ์์กดํ์ง ์๋ ํจ์
* ์ฌ์ด๋ ์ดํํธ(Side-effect) : ํจ์๊ฐ ์์ ์ ์ผ ์ธ์ ์ปดํฌ๋ํธ ๋ฐ์ ์ํฅ์ ์ฃผ๋ ์ผ์ ํ๋ ๊ฒ
dispatch ํจ์
useReducer(reducer, initialArg, init?)
//์ฐธ๊ณ : init์ด ์์ผ๋ฉด initialArg๋ฅผ ๋ฐ๋ก state๋ก ์ฐ์ง ์๊ณ , init์ ํ ๋ฒ ์คํํด์ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ด๊ธฐ ์ํ๋ก ์ฌ์ฉํ๋ค.
useReducer์ ์ํด ๋ฐํ๋๋ dispatch ํจ์๋ ์ ์ผํ ์ธ์์ธ ์ก์ (action)์ reducer ํจ์์ ์ ๋ฌํ๋ ํจ์์ด๋ค.
function MyComponent() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
// ...
}
useReducer ์ฌ์ฉ ์์
import { useReducer } from "react";
function reducer(state, action) {
//ํ์ฌ ์ํ์ ์ฌ์ฉ์ ์ก์
์ ์ ๋ฌ๋ฐ์
switch (
action.type //reducer์์ ์ ์ํด๋์ ์ก์
๋ค
) {
case "increment":
return { count: state.count + 1 }; //์
๋ฐ์ดํธ ๋ ์ํ๋ฅผ ๋ฐํ
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
export default function CounterContextProvider({ children }) {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
<button
onClick={() => {
//dispach ํจ์๋ฅผ ํตํด reducer ํจ์์ action โ์ฌ์ฉ์๊ฐ ๋ฐฉ๊ธ ํ ์ผโ ์ ๋ฌ
dispatch({ type: "increment" });
}}
>
Increment count
</button>
<button
onClick={() => {
dispatch({ type: "decrement" });
}}
>
Increment count
</button>
<p>current count: {state.count}</p>
</>
);
}
๋๊ธ๋จ๊ธฐ๊ธฐ