๐ŸŽฏVanillaJS redux

์„ฑ๋ฏผ๊ฐœ๋ฐœ๋กœ๊ทธยท2021๋…„ 12์›” 18์ผ
0

redux

๋ชฉ๋ก ๋ณด๊ธฐ
1/4

๋ฆฌ๋•์Šค(Redux)

๋ฐ”๋‹๋ผ ๋ฆฌ๋•์Šค

๋ฆฌ๋•์Šค ๋Š” ์ƒํƒœ(state) ๋ฐ์ดํ„ฐ๋ฅผ ์ „์—ญ์œผ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋‹ค ๋ฆฌ์•กํŠธ ํ•œ์—์„œ ๋‚˜์˜จ๊ฒŒ ์•„๋‹Œ ๋ฐ”๋‹๋ผ์—์„œ๋„ ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

import { createStore } from 'redux'; // npm i redux -> import

const reducer = (state = 0) => {
  // ๋ฐ์ดํ„ฐ ์ƒํƒœ๊ฐ’์„ ๋ฐ”๊พธ๊ณ  modify ํ•˜๋Š”๊ฑธ ์ฑ…์ž„ ์ ธ์ฃผ๋Š” ํ•จ์ˆ˜
  // ์›ํ•˜๋Š” ๋™์ž‘ ์ฝ”๋“œ

  return state;
};

const store = createStore(reducer /*์ฝœ๋ฐฑํ•จ์ˆ˜*/); // createStore ํ•จ์ˆ˜๋กœ state๋ฐ์ดํ„ฐ ์ €์žฅ ๊ณต๊ฐ„์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.

// console.log(store.getState()) ํ†ตํ•ด์„œ reducer ๋ฆฌํ„ด ๊ฐ’์„ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

reducer modify

const reducer = ((state = 0), action); //๋งŒ์•ฝ state ๊ฐ’์ด undefined ์ด๋ฉด 0์œผ๋กœ ์ดˆ๊ธฐํ™”

action: redux ์—์„œ ํ•จ์ˆ˜๋ฅผ(reducer) ๋ถ€๋ฅผ๋•Œ ์“ฐ๋Š” ๋‘๋ฒˆ์งธ
ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋‹ค
action ์€ ๊ฐ์ฒด๋กœ ์ธ์‹
์˜ˆ):{type:"somthing" ๋“ฑ๋“ฑ} ๊ฐ์ฒด๋กœ ๋ฐ›์•„ ๋“ค์ธ๋‹ค.

ํ•จ์ˆ˜์™€ ์†Œํ†ตํ• ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜ dispatch()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†Œํ†ตํ•  ์ˆ˜ ์žˆ๋‹ค.

subscribe() ํ•จ์ˆ˜๋Š” store ์•ˆ์— ์žˆ๋Š” ๋ณ€ํ™”๋ฅผ ์•Œ๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

์˜ˆ) ๋”ํ•˜๊ธฐ์™€ ๋นผ๊ธฐ๋ฅผ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด ๋ณผ๊บผ๋‹ค.

import { createStore } from 'redux';

const add = document.getElementById('add');
const minus = document.getElementById('minus');
const number = document.querySelector('span');

number.innerText = 0;

const countModifier = (count = 0, action) => {
  if (action.type === 'ADD') {
    //action {type:"ADD"} ์ผ๋•Œ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ
    return count + 1;
  } else if (action.type === 'MINUS') {
    //action {type:"MINUS"} ์ผ๋•Œ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ
    return count - 1;
  } else {
    return count;
  }
};

const countStore = createStore(countModifier); // ์ €์žฅ์†Œ๋ฅผ ์„ ์–ธ ๋ฐ countModifier์ฝœ๋ฐฑํ•จ์ˆ˜  ํ• ๋‹น.

const onChange = () => {
  number.innerText = countStore.getState(); //store ์— ์žˆ๋Š” ์ƒํƒœ๊ฐ’์ถœ๋ ฅ
};

countStore.subscribe(onChange); // store ์•ˆ์— ๊ฐ’์ด ๋ณ€ํ™” ํ• ๋•Œ๋งˆ๋‹ค onChange ํ•จ์ˆ˜ ์‹คํ–‰

const handleAdd = () => {
  countStore.dispatch({ type: 'ADD' }); // ์†Œํ†ต ํ•จ์ˆ˜ dispatch ์‚ฌ์šฉํ•ด์„œ  ์†Œํ†ตํ•˜๊ธฐ.
};

const handleMinus = () => {
  countStore.dispatch({ type: 'MINUS' }); // ์†Œํ†ต ํ•จ์ˆ˜ dispatch ์‚ฌ์šฉํ•ด์„œ  ์†Œํ†ตํ•˜๊ธฐ.
};

add.addEventListener('click', handleAdd);
minus.addEventListener('click', handleMinus);

reducer ๋ฅผ ํ˜ธ์ถœํ• ๋•Œ ๋ฆฌํ„ดํ•˜๋Š” ๊ฐ’์€ ์ ˆ๋Œ€ mutate ํ•˜๋ฉด ์•ˆ๋œ๋‹ค. mutate ํ•˜๋Š” ๋Œ€์‹ ์— ์ƒˆ๋กœ์šด Object ๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฆฌํ„ดํ•ด์•ผํ•œ๋‹ค.
** ์ƒํƒœ๊ฐ’์„ ๋ฐ”๊พธ๋Š” ๋ฐฉ๋ฒ•์€ action ์ด ์œ ์ผํ•˜๋‹ค ๋ฐ–์—์„œ ์ƒํƒœ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.

countStore.getState() +=1 // Bad!!!

mutation:

let friends = ['bob']; // friends ๋ผ๋Š” ๋ฐฐ์—ด ์„ ์–ธ
friends.push('ellie'); // ์ด๋Ÿฐ๋ฐฉ์‹์œผ๋กœ ๋ฐฐ์—ด์„ ๋ณ€ํ˜• ์‹œํ‚ค๋Š”๊ฒƒ์ด mutation ์ด๋‹ค.

์ƒˆ๋กœ์šด Object ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•:

let friends = ['bob'];
friends = [...friends, 'ellie']; //์ด๋Ÿฐ์‹์œผ๋กœ ์ƒˆ๋กœ์šด object ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ https://redux.js.org/basics/reducers

0๊ฐœ์˜ ๋Œ“๊ธ€