๋ฆฌ๋์ค ์ฒ์๋ถํฐ ์์ํ๊ธฐ
๋ชจ๋ ์ค์นํ๊ธฐ
npm i redux react-redux
๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด require๋ก ๋ถ๋ฌ์จ๋ค.
const redux = require("redux");
์ ์ฅ์ ๋ง๋ค๊ธฐ
const store = redux.createStore();
์ ์ฅ์ ๋ง๋ค๊ธฐ (๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํจ)(๊ด๋ฆฌํ๋ ๋ฐ์ดํฐ๋ ๊ฒฐ๊ตญ ๋ฆฌ๋์ ํจ์์ ์ํด ๊ฒฐ์ ๋๋ค.๋ฆฌ๋์ ํจ์๊ฐ ์๋ก์ด ์ํ ์ค๋
์ท์ ์์ฑํ๋๊น)
(๋ฆฌ๋์๋ ์ก์
์ด ๋์ฐฉํ ๋๋ง๋ค ์๋ก์ด ์ํ ์ค๋
์ท์ ๋ฑ์ด๋ด์ผ ํ๋ค.)
const counterReducer = (state = { counter: 0 }, action) => {
return {
counter: state.counter + 1,
};
};
โฅ ์ ํจ์ ํด์: ์ฐ๋ฆฌ๊ฐ ์๋์ผ๋ก ๋ฐ๋ ๊ธฐ์กด ์ํ๋ฅผ ์ฐธ์กฐํ๊ณ , ์ํ์ ์ ์ฅ๋ ๊ธฐ์กด์ counter ๊ฐ์ ์ก์ธ์คํ๊ณ , ์๋ก ๋ฆฌํด๋ ์ํ์ ์๋ก์ด counter ๊ฐ์ผ๋ก์ ๊ฑฐ๊ธฐ์ 1์ ๋ํ๋ค.
โญ๏ธโญ๏ธ
๋ฆฌ๋์ ํจ์๋ ํ์ค ์๋ฐ์คํฌ๋ฆฝํธ ํจ์์ง๋ง, ๋ฆฌ๋์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํด ํธ์ถ๋ ๊ฑฐ๋ค. ํญ์ 2๊ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ๋๋ค. (๊ธฐ์กด์ ์ํ์ ๋ฐ์ก๋ ์ก์
)
๊ทธ๋ฆฌ๊ณ ์ด ๋ฆฌ๋์ ํจ์๋ ์ด๋ค ์ถ๋ ฅ์ ๋ฆฌํดํด์ผ๋ง ํ๋ค. ํญ์ ์๋ก์ด ์ํ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํด์ผ๋ง ํ๋ค. ๊ทธ๋์ ๋ฆฌ๋์ ํจ์๋ ์์ํ ํจ์๊ฐ ๋์ด์ผ ํ๋ค.
(์์ํจ์: ๋์ผํ ์
๋ ฅ๊ฐ์ ๋ฃ์ผ๋ฉด ํญ์ ์ ํํ ๊ฐ์ ์ถ๋ ฅ์ด ์ฐ์ถ๋๋ค. ์ด๋ ํ side effect๊ฐ ์๋ค. )
์๋ฅผ๋ค์ด HTTP์์ฒญ์ ์ ์กํ๋ค๊ฑฐ๋ ๋ญ๊ฐ๋ฅผ ๋ก์ปฌ ์ ์ฅ์์ ๊ธฐ๋กํ๋ค๊ฑฐ๋ ๋ก์ปฌ์ ์ฅ์์ ๋ญ๊ฐ๋ฅผ ๊ฐ์ ธ์ค์ง ๋ง์์ผํ๋ค.
๋์ ์ ๋ฆฌ๋์๋ ๋ฆฌ๋์ค๊ฐ ์ ๊ณตํ๋ ์
๋ ฅ์ ์ทจํ๊ณ ์์๋ ์ถ๋ ฅ๋ฌผ์ธ ์๋ก์ด ์ํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์์ํจ์๊ฐ ๋์ด์ผ ํ๋ค.
๋ฆฌ๋์ ํจ์์ ์ถ๋ ฅ์ ์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฒด! ๊ทธ ์ด์ ๋ ๋๋ถ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ํ๋ ํ๋์ ๊ฐ ์ด์์ ์๋ฏธํ๊ธฐ ๋๋ฌธ! ํ์ง๋ง ์ด๋ก ์ ์ผ๋ก๋ ์ด๋ ํ ๊ฐ ์ ํ๋ ๊ฐ๋ฅ!
โญ๏ธโญ๏ธโญ๏ธ
๋ฆฌ๋์ ํจ์์ state={conuter:0}๋ผ๊ณ state ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ๊ฐ์ ์ค ์ด์ !
state ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ๊ฐ์ ์ฃผ์ง ์๋๋ค๋ฉด "Cannot read properties of undefined (reading 'counter')" ์ค๋ฅ ๋ฐ์!
createStore๋ฅผ ์ด์ฉํด์ ์ ์ฅ์๋ฅผ ๋ง๋ค์๊ณ , ๊ทธ ์ ์ฅ์์ ํ์ํ counterReducer๊ฐ ์๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ฆฌ๋์์ ์ฐ๋ฆฌ๋ ์ํ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค. ๊ธฐ์กด ์ํ ์นด์ดํฐ์ 1์ ๋ํด์ ์นด์ดํฐ๋ฅผ ์ค์ ํ๋ค. ๊ทธ ์ ์ฅ์๊ฐ ์ด๊ธฐํ๋ ๋ ๋ฆฌ๋์ค๊ฐ ์ด ๋ฆฌ๋์๋ฅผ "์ฒ์์ผ๋ก" ์คํํ๋ค๋๊ฒ ๋ฌธ์ ๋ค.
์ ์ฅ์๊ฐ ์์ฑ๋ ๋ counterReducer ๋ผ๋ ๋ฆฌ๋์ ํจ์๊ฐ ์์ ์๋ ์ฝ๋๊ฐ ์คํ๋๋๋ฐ, ๋ฌธ์ ๋ ๊ทธ ์์ ์ ์ํ๊ฐ ์ ์๋์ด ์์ง ์๋๋ค!
์ฒ์์ผ๋ก ์คํ๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด ์ํ๊ฐ ์๋๊ฒ์ด๋ค.
๊ทธ๋์ ๋ฆฌ๋์ ํจ์๊ฐ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๋ state ์ ๊ธฐ๋ณธ๊ฐ์ ์ฃผ์ด์ผ ํ๋ค!! (๋ฌ๋ฆฌ ์ ์๋์ด ์์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ด ๊ฐ์ ๋๋ค. )
์ต์ด ์คํ๋ ๋, ๊ฐ์ด ์๊ฒ ํ๋๊ฑฐ๊ณ , ๊ทธ ๋ค์๋ถํฐ๋ ๊ธฐ์กด ์ํ๊ฐ ์๊ฒ ๋๋ค. (๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉ๋์ง ์๋๋ค. )
๊ทธ๋์ ๋ฆฌ๋์ ํจ์์ state={conuter:0}๋ผ๊ณ state ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ๊ฐ์ ์ค๊ฑฐ๋ค.
์ ๋ฆฌ ๐
๋ฆฌ๋์๊ฐ ์ฒ์ ํธ์ถ๋ ๋, state๊ฐ์ undefined๊ฐ ๋๋ค.
๋ฐ๋ผ์ state์ ์ด๊น๊ฐ์ ์ง์ ํด์ ์ก์ ์ด ๋ฐ์ํ๊ธฐ ์ ์ ์ด ์ผ์ด์ค์ ๋ํด ์ฒ๋ฆฌํด์ค์ผ ํ๋ค. ๋ง์ฝ ์ด๊น๊ฐ์ ์ค์ ํด์ฃผ์ง ์์ ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
๋ฆฌ๋์์ ์ ์ฅ์ ์ฐ๊ฒฐํด์ฃผ๊ธฐ
const store = redux.createStore(counterReducer);
์ ์ฅ์์ ์์ ํ๋ ๊ฑด ๋ฆฌ๋์ ํจ์์ด๊ธฐ ๋๋ฌธ์ ์ ์ฅ์๋ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๋ฆฌ๋์ ํจ์๊ฐ ์ด๋ค ํจ์์ธ์ง ์์์ผ ํ๋ค.
TIP ์ด๊ธฐ์ํ๊ฐ ๊ถ๊ธํ ๋
console.log(store.getState());
์ก์ ๋ง๋ค์ด์ฃผ๊ธฐ (์ ์ฅ์๋ฅผ ๊ตฌ๋ ํ ๋๊ตฐ๊ฐ์ ๋ฐ์กํ ์ ์๋ ์ก์ ์ด ํ์ํ๋ค!)
const counterSubscriber = () => {
const latestState = store.getState();
console.log(latestState);
};
์ด๋ ํ ํ๋ผ๋ฏธํฐ๋ ๋ฐ์ง ์๋๋ค.
ํจ์ ์์์ ์ฐ๋ฆฌ๋ ์ ์ฅ์์ ๊ฐ์ getState()๋ฅผ ํธ์ถํ ์ ์๋ค.
getState()๋ createStore()๋ก ์์ฑ๋ ์ ์ฅ์์์ ์ฌ์ฉํ ์ ์๋ ๋ฉ์๋๋ค. ๊ทธ๋ฆฌ๊ณ ์
๋ฐ์ดํธ๋ ํ์ ์ต์ ์ํ ์ค๋
์ท์ ์ ๊ณตํ๋ค.
๊ทธ๋ผ ์ด ๊ตฌ๋
ํจ์๋ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ํธ๋ฆฌ๊ฑฐ๋๋ค. ํธ๋ฆฌ๊ฑฐ๊ฐ ๋๋ฉด getState()๋ฉ์๋๋ก ๋ณ๊ฒฝ๋ ํ์ ์ต์ ์ํ๋ฅผ ๋ฐ์ ์ ์๋ค.
๋ฆฌ๋์ค๊ฐ ๊ตฌ๋ ํจ์๋ฅผ ์ธ์ํ๋๋ก ํด์ฃผ๊ธฐ
( ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ด ํจ์๋ฅผ ์คํํ๋ผ๊ณ ๋งํด์ค์ผํ๋ค. ์ ์ฅ์์ ๊ฐ์ subscribe() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋๋ค. )
store.subscribe(counterSubscriber);
subscribe()๋ฉ์๋๋ ๊ตฌ๋
ํจ์๋ฅผ ๋ฐ๊ณ , ๋ฆฌ๋์ค๋ ๋ฐ์ดํฐ์ ์ ์ฅ์๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๊ทธ๊ฑธ ์คํํด์ค๊ฑฐ๋ค.
์ฌ๊ธฐ์ counterSubscriber๋ฅผ ์คํํ์ง ์๋๊ฒ์ด ์ค์ํ๋ค!! ๊ทธ๋ฅ ๊ฐ๋ฆฌํฌ๋ฟ์ด๋ค! ๊ทธ ์ด์ ๋ ๋ฆฌ๋์์ ๊ตฌ๋
ํจ์ ๋ชจ๋ ๋ฆฌ๋์๊ฐ ์คํํ๊ธฐ ๋๋ฌธ!
์ก์ ๋ณด๋ด์ฃผ๊ธฐ (dispatch)
store.dispatch({ type: "increment" });
dispatch()๋ ์ก์
์ ๋ฐ์กํ๋ ๋ฉ์๋์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ก์
์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ด๋ค.
์๋ณ์ ์ญํ ์ ํ๋ type ํ๋กํผํฐ๋ฅผ ๊ฐ์ง ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ด๋ค. type๋ค์๋ ๊ณ ์ ํ ๋ฌธ์์ด์ด ๋์ด์ผํ๋ค.
๊ทธ๋์ผ ์ฐ๋ฆฌ๊ฐ ๋ฐ์กํ๋ ๋ชจ๋ ๊ณ ์ ํ ์ก์
๋ค์ด ๋ฆฌ๋์์์ ๋ค๋ฅธ ๊ฒ๋ค์ ์ ๋ฐํ๊ฒ ๋๋ค.
โญ๏ธโญ๏ธ ์์์ ์ก์
์ increment์ด๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํ ๋ ๋ฆฌ๋์ ๋ด๋ถ์์ ๋ค๋ฅธ ์ก์
์์๋ ๋ค๋ฅธ ์ผ์ ํ๋๊ฒ ๋ชฉํ์ด๋ค. ๊ทธ๋์ counterReducer ํจ์์ ํ๋ผ๋ฏธํฐ ์์ ๋๋ฒ์งธ ๋ณ์๋ก action์ด ์๋ ๊ฑฐ๋ค.
ํ์ฌ ์ํ๋ฅผ ๋ฐ๊ณ , ๋์คํจ์น ๋ ์ก์
์ ๋ฐ์ผ๋ฉด ๊ทธ ๋ฆฌ๋์๊ฐ ๋์๊ฐ๊ฒ ํ ๊ฒ์ด๋ค.
if ์ก์
ํ์
์ด increment์ ๊ฐ๋ค๊ณ ํ๋ฉด ์นด์ดํฐ์ ์ฆ๊ฐ๋ฅผ ์ํค๊ณ ์ถ๋ค. ๊ทธ๊ฒ ์๋๋ผ ๋ค๋ฅธ ์ก์
์ด๋ฉด ๋ณํ์ง ์์ ์ํ๋ฅผ ๋ฆฌํดํ๊ฒ ๋ค.
๊ทธ๋ฆฌ๊ณ ์ํ์ ์๋ ๋ฐธ๋ฅ๋ฅผ ๋ฐ๊ฟ ๊ฒ์ด๋ค. ์๋ํ๋ฉด ์ด๊ธฐํ ๋๋ฌธ์ ์นด์ดํฐ๋ฅผ ์ฆ๊ฐํ์ง ์์๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ํดํธ ๊ฐ์ ๋ฐํํ ๊ฒ์ด๋ค.
const counterReducer = (state = { counter: 0 }, action) => {
if (action.type === "increment") {
return {
counter: state.counter + 1,
};
}
return state;
};
// ์ด๋ฌ๊ณ ์คํ์ํค๋ฉด { counter: 1 } ๋ผ๊ณ ๋์จ๋ค. ์ด๊ธฐํ ๋๋ฌธ์ ๋์ด์ ์ฆ๊ฐํ์ง ์๋๋ค.
โฅ ์ ํจ์ ํด์: if ์ก์ ํ์ ์ด increment์ ๊ฐ๋ค๊ณ ํ๋ฉด ์นด์ดํฐ์ ์ฆ๊ฐ๋ฅผ ์ํค๊ณ ์ถ๋ค. ๊ทธ๊ฒ ์๋๋ผ ๋ค๋ฅธ ์ก์ ์ด๋ฉด ๋ณํ์ง ์์ ์ํ๋ฅผ ๋ฆฌํดํ๊ฒ ๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ์ ์๋ ๋ฐธ๋ฅ๋ฅผ ๋ฐ๊ฟ ๊ฒ์ด๋ค. ์๋ํ๋ฉด ์ด๊ธฐํ ๋๋ฌธ์ ์นด์ดํฐ๋ฅผ ์ฆ๊ฐํ์ง ์์๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ํดํธ ๊ฐ์ ๋ฐํํ ๊ฒ์ด๋ค.
store.dispatch({ type: "decrement" });
// { counter: 1 } { counter: 0 } ์ด๋ ๊ฒ ๋์จ๋ค.
์ฒซ๋ฒ์งธ ์ถ๋ ฅ์ ์ฆ๊ฐ ์ก์
๋ค์์ store.subscribe(counterSubscriber);์์ ๋์จ๊ฑฐ๋ค. ๊ทธ๋ฆฌ๊ณ ๋์ ์ก์
์ ๋ ๋ง๋์ store.subscribe(counterSubscriber);๋ฅผ ํธ๋ฆฌ๊ฑฐํ๊ณ ์นด์ดํฐ๊ฐ 0์ด ๋๊ฑฐ๋ค.
๋ฆฌ๋์ค๋ ๋ฆฌ์กํธ์๋ง ์ ํ๋์ง ์๋๋ค.
const redux = require("redux");
const counterReducer = (state = { counter: 0 }, action) => {
return {
counter: state.counter + 1,
};
};
const store = redux.createStore(counterReducer);
console.log(store.getState()); // ์ฌ๊ธฐ์ ์ฝ์์ฐฝ์ { counter: 1 } ์ฐํ๋ค. ์ด๊ธฐ์ํ๊ฐ 1
const counterSubscriber = () => {
const latestState = store.getState();
console.log(latestState);
};
store.subscribe(counterSubscriber);
store.dispatch({ type: "increment" }); // ์ฌ๊ธฐ์ ์ฝ์์ฐฝ์ { counter: 2 } ์ฐํ๋ค. ์ด๊ธฐ์ํ์ +1
const redux = require("redux");
const counterReducer = (state = { counter: 0 }, action) => {
if (action.type === "increment") {
return {
counter: state.counter + 1,
};
}
if (action.type === "decrement") {
return {
counter: state.counter - 1,
};
}
return state;
};
const store = redux.createStore(counterReducer);
console.log(store.getState()); //์ฌ๊ธฐ์ ์ฝ์์ฐฝ์ { counter: 0 } ์ฐํ๋ค. ์ด๊ธฐํ ๋๋ฌธ์ counter๋ฅผ ์ฆ๊ฐ์ํค์ง ์๋๋ค. ๋์ ๋ํดํธ ์ํ๋ฅผ ๋ฆฌํดํ๋ค.
const counterSubscriber = () => {
const latestState = store.getState();
console.log(latestState);
};
store.subscribe(counterSubscriber);
store.dispatch({ type: "increment" }); // ์ฌ๊ธฐ์ ์ฝ์์ฐฝ์ { counter: 1 } ์ฐํ๋ค. ์ด๊ธฐ์ํ์ +1
store.dispatch({ type: "decrement" }); // ์ฌ๊ธฐ์ ์ฝ์์ฐฝ์ { counter: 0 } ์ฐํ๋ค. ํ์ฌ์ํ์ -1
์ฐธ๊ณ )
์ ๋ฐ๋ฏธ ๋ฆฌ์กํธ ์๋ฒฝ๊ฐ์ด๋