Redux๐Ÿ’ก

๐Ÿงกredux์˜ ๊ตฌ์กฐ

โœจAction Type ์ •์˜

  • Reducer์—์„œ ์‚ฌ์šฉ ํ•  Type๋“ค์„ ๋ฏธ๋ฆฌ ๋ณ€์ˆ˜๋กœ ์ •์˜ํ•œ๋‹ค.
// src/modules/user.js

  //const ํƒ€์ž…๋ช… = '์‚ฌ์šฉ ๋  reducer/ํƒ€์ž…๋ช…'

  export const ADD_USER = 'user/ADD_USER'
  export const DELETE_USER = 'user/DELETE_USER'
  • ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘์–ด ํ˜‘์—…์‹œ์— ๊ฐ€๋…์„ฑ์„ ๋†’์ž„
  • ์‚ฌ์šฉ๋˜๋Š” reducer๋ฅผ ํ•จ๊ป˜ ๋ช…์‹œํ•˜์—ฌ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฆฌ๋“€์„œ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉ ์‹œ, ํƒ€์ž…๋ช…์˜ ์ค‘๋ณต์— ๋”ฐ๋ฅธ ์˜ค๋ฅ˜ ์˜ˆ๋ฐฉ
  • export ํ•˜์—ฌ ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์„ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ณ , ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋กํ•จ
  • ํ˜น์‹œ๋‚˜ ์žˆ์„ ์˜คํƒ€ ๋ฐฉ์ง€

โœจAction ์ƒ์„ฑํ•จ์ˆ˜

action๊ฐ์ฒด : {type: ~~ , payload: ~~}์™€ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ redux์—์„œ๋Š” action๊ฐ์ฒด๋ผ๊ณ  ํ•จ

dispatch : action๊ฐ์ฒด๋ฅผ dispatch()ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด reducer๋กœ ๋ณด๋‚ด๋Š” ํ–‰์œ„๋ฅผ dispatch๋ผ๊ณ  ํ•จ

action์ƒ์„ฑํ•จ์ˆ˜ : dispatch()์— ์ „๋‹ฌ ํ•  ํƒ€์ž…๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ returnํ•˜๋Š” ํ•จ์ˆ˜

  • ๋งค๋ฒˆ dispatch({type: ~~, payload: ~~})๋ผ๊ณ  ์ฝ”๋“œ์—์„œ ๋ช…๋ช…ํ•˜๊ธฐ๋ณด๋‹จ action๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ dispatch()์— ์ „๋‹ฌ => dispatch(addUser(user))
  • payload ์— ์ธ์ž๋กœ ๋ฐ›์€ ๊ธฐํƒ€ ๋ฐ์ดํ„ฐ๋“ค์„ ๋‹ด์Œ
// src/modules/user.js

  export function addUser(user) {
    return {
      type: ADD_USER,
      payload: user,
    };
  }

  export function deleteUser(userId) {
    return {
      type: DELETE_USER,
      payload: { userId },
    };
  }

โœจReducer

  • initialState์— ๊ธฐ๋ณธ๊ฐ’์ด ๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„์„œ state์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ „๋‹ฌ
  • state์˜ ๊ฐ’์€ ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•ด์•ผํ•จ
    • ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ math.random(), new Date() ๋“ฑ.. ์˜ ์•„์ดํ…œ ์‚ฌ์šฉ๊ธˆ์ง€
    • ์œ„์™€ ๊ฐ™์ด ๊ฐ’์ด ๋ณ€ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ์•ก์…˜ ์ƒ์„ฑ ์‹œ ์ฒ˜๋ฆฌ
  • ๋ฆฌ์•กํŠธ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ฐ’์˜ ๋ณ€ํ™”๋กœ state๊ฐ’์˜ ๋ณ€ํ™”๋ฅผ ์•Œ์•„์ฐจ๋ฆฐ๋‹ค.
    • push๋“ฑ ๋ฉ”๋ชจ๋ฆฌ๊ฐ’์˜ ๋ณ€ํ™”๊ฐ€ ์—†๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๊ธˆ์ง€
    • concat ํ˜น์€ ...(spread) ์‚ฌ์šฉ
// src/modules/user.js

  const initialState = [
    {
      id: 1,
      name: "Leanne Graham",
      email: "Sincere@april.biz",
    },
    {
      id: 2,
      name: "Ervin Howell",
      email: "Shanna@melissa.tv",
    },
    {
      id: 3,
      name: "Clementine Bauch",
      email: "Nathan@yesenia.net",
    }
  ]

  export default function user(state = initialState, action) {
    switch (action.type) {
      case ADD_USER:
        return [...state, action.payload];

      case DELETE_USER:
        return state.filter((item) => item.id !== action.payload.userId);
      default:
        return state;
    }
  }

โœจStore (๊ธฐ๋ณธ)

  • store๋ž€ ์•ž์—์„œ ์ž‘์„ฑํ•œ ๋ฆฌ๋“€์„œ์™€ ์ƒํƒœ๋ฅผ ๋‹ด์•„๋†“์€ ๊ฒƒ
  • ํ•˜๋‚˜์˜ ์•ฑ์—๋Š” ํ•˜๋‚˜์˜ store๋งŒ ์กด์žฌํ•˜๋„๋ก ํ•˜๋Š”๊ฒƒ์ด ์›์น™
  • store์—์„œ ์‚ฌ์šฉ ํ•  reducer๋ฅผ ์ •์˜ ํ›„ Provider๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ์‹ธ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ์—์„œ๋“  ๋ฆฌ๋“€์„œ์™€ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•จ
// src/store/index.js

  import { legacy_createStore as createStore } from "redux";
  import user from "../modules/user";

  const store = createStore(user);

  export default store;

ํ˜„์žฌ createStore๋Š” deprecate๋˜์–ด redux-toolkit์˜ configureStore๋กœ ์‚ฌ์šฉ๋˜๊ธธ ๊ถŒ์žฅ๋˜์ง€๋งŒ ์ˆœ์ˆ˜ redux๋งŒ ์‚ฌ์šฉ ์‹œ ์œ„์™€ ๊ฐ™์ด legacy_createStore๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Œ

  • ์œ„์™€ ๊ฐ™์ด store ์ž‘์„ฑ ํ›„ Provider๋กœ ์•ฑ ์ „์ฒด๋ฅผ ๊ฐ์‹ผ ๋’ค store๋ฅผ ์ „๋‹ฌ
import { Provider } from "react-redux";
import store from "./store";
import User from "./components/User";

function App() {
  return (
    <Provider store={store}>
      <User />
    </Provider>
  );
}

export default App;

โœจStore (Reducer๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ ๋•Œ)

  • ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ combineReducers() ๋‚ด์— ์‚ฌ์šฉ ํ•  Reducer๋ฅผ ๋ชจ๋‘ ์ •์˜ ํ•œ ๋’ค, ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ store์— ์ „๋‹ฌํ•œ๋‹ค
const rootReducer = combineReducers({
  ํ‚ค: ๋ฆฌ๋“€์„œ,
  ํ‚ค: ๋ฆฌ๋“€์„œ,
});
// src/store/index.js

import { combineReducers,legacy_createStore as createStore } from "redux";
import counter from "../modules/counter";
import user from "../modules/user";

const rootReducer = combineReducers({
  counter,
  user,
});

const store = createStore(rootReducer);

export default store;
  • ๋˜‘๊ฐ™์ด Provider๋กœ App์ „์ฒด๋ฅผ ๊ฐ์‹ธ์ฃผ์–ด store๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋ฉด ๋!

๐ŸงกRedux Hooks

  • ์œ„์˜ Redux๊ตฌ์กฐ๋ฅผ ์™„์„ฑํ•˜๊ณ  ๋‚˜๋ฉด ๊ธฐ๋ณธ ์„ธํŒ…์€ ์™„๋ฃŒ
  • ์ด์ œ Reducer์— ์ •์˜ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž

โœจuseSelector()

  • redux ๋กœ ๊ด€๋ฆฌ ์ค‘์ธ ์ƒํƒœ(state)๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ Hook
  • useSelector()๋Š” reducer์— ์ •์˜ ๋œ state๊ฐ’์„ ๋ฐ›์•„์˜ด
  • store์— ์—ฌ๋Ÿฌ๊ฐœ์˜ reducer๋ฅผ ์ •์˜ ํ•œ ๊ฒฝ์šฐ combineReducers์—์„œ ์ •์˜ํ•œ ํ•ด๋‹น reducer์˜ key๊ฐ’์œผ๋กœ ์›ํ•˜๋Š” reducer์˜ state๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค
//src/components/User

  import { useSelector } from "react-redux";

  function User() {
    // reducer๊ฐ€ ํ•œ๊ฐœ์ผ ๋•Œ (๊ธฐ๋ณธ)
    const users = useSelector((state) => state);
    
    // reducer๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ ๋•Œ
    const users = useSelector((state) => state.user);
    const number = useSelector((state) => state.counter);
    
    return ...
  }
  • dispatch๋ฅผ ํ†ตํ•ด state์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด useSelector๋กœ ๋ฐ›์•„์˜จ state์˜ ๊ฐ’๋„ ์ž๋™์œผ๋กœ ๊ฐฑ์‹  ๋จ

โœจuseDispatch()

  • dispatch ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” Hook
  • ๋งŒ๋“ค์–ด์ง„ ์•ก์…˜ ๊ฐ์ฒด๋ฅผ Reducer ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•ด์ฃผ๋Š” Hook
  • action๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ „๋‹ฌํ•ด๋„ ๋˜์ง€๋งŒ ์œ„์—์„œ ์ž‘์„ฑํ•œ action์ƒ์„ฑํ•จ์ˆ˜ ๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๋ฐฉ์‹์ด ์ฃผ๋กœ ์‚ฌ์šฉ ๋จ
import { useDispatch, useSelector } from "react-redux";
import { addUser, deleteUser } from "../modules/user";

function User() {
  const users = useSelector((state) => state.user);
  const dispatch = useDispatch();

  const onAdd = (user) => {
    dispatch(addUser(user));
  };

  const onDelete = (userId) => {
    dispatch(deleteUser(userId));
  };
  
  return (
    <div>
      {users.map((user) => (
        <div key={user.id}>
          <p>{user.name}</p>
          <button onClick={() => onDelete(user.id)}>์ œ๊ฑฐ</button>
        </div>
      ))}
      <button onClick={() => {onAdd({ name: "john" })}}>์ถ”๊ฐ€</button>
    </div>
  );
}

export default User;

๋งˆ์น˜๋ฉฐ๐Ÿ™Œ

Redux ๋ณ„ ๊ฑฐ ์—†๋„ค!!!

...
๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ๋‹ค.... ์ด๋•Œ๊นŒ์ง€๋Š”.......๐Ÿฅฒ
๋”ฑ ์ด๋งŒํผ๋งŒ ์•Œ๋ฉด ์•ˆ๋˜๋Š”๊ฑธ๊นŒ์š”......

๊ทธ๋ž˜๋„ ์ฒ˜์Œ ๋ฆฌ์•กํŠธ๋ฅผ ๋ฐฐ์šธ ๋• ์ด ์ปดํฌ๋„ŒํŠธ์—์„œ ์ € ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋งˆ๊ตฌ๋งˆ๊ตฌ ์ฃผ๊ณ ๋ฐ›์•„์•ผํ•˜๋Š”๊ฒŒ ๊ทธ๋ ‡๊ฒŒ ๊ณจ์น˜๊ฐ€ ์•„ํ”Œ ์ˆ˜ ์—†์—ˆ๋Š”๋ฐ ์ด๋Ÿฐ ๋„๊ตฌ๋“ค์„ ์‚ฌ์šฉํ•  ์ค„ ์•Œ๊ฒŒ ๋˜๋ฉด์„œ ํ•œ๊ฒฐ ๋‹ค๋ฃจ๊ธฐ๊ฐ€ ์ˆ˜์›”ํ•ด์ง„ ๋Š๋‚Œ์ด๊ธด ํ•˜๋‹ค..!!

๋ฐฐ์šฐ๋Š”๊ฒŒ ์–ด๋ ต๊ธด ํ•˜์ง€๋งŒ ์•„๋Š”๊ฒŒ ๋งŽ์•„์งˆ์ˆ˜๋ก ์ฝ”๋“œ ๋‹ค๋ฃจ๊ธฐ๊ฐ€ ์‰ฌ์›Œ์ง€๋Š”๊ฒŒ ๋Š๊ปด์ง€๋‹ˆ... ์—ด์‹ฌํžˆ ํ•ด๋ด์•ผ๊ฒ ์ฃ ..!!?

์ผ๋‹จ ์ฃผ๋ง์„ ์‰ฌ๊ณ  ๋‹ค์Œ์ฃผ์—๋Š” redux์˜ middleware์™€ toolkit๋„ ์ •๋ฆฌํ•ด๋ด์•ผ์ง€... ๐Ÿฅฒ (๊ทธ๋งŒํ•˜๊ณ ์‹ถ์–ด์š”...๐Ÿซ )

profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์„ฑ์žฅ์ผ๊ธฐ ๐Ÿ’ญ

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