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

Redux์˜ ์žฅ๋‹จ์ 

Redux ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

  1. Redux ์„ค์น˜ ์›ํ•˜๋Š” ๋ฒ„์ „์ด ์žˆ๋‹ค๋ฉด @๋ฒ„์ „๋ฒˆํ˜ธ ์ถ”๊ฐ€

    image.png

  2. Redux Store(์ด๊ด„์ฑ…์ž„์ž) ์ƒ์„ฑ (.js ํŒŒ์ผ๋กœ ์ƒ์„ฑ) ๊ฒฝ๋กœ ์˜ˆ์‹œ) src/store/store.js

  3. Slices(์ตœ์†Œ๋‹จ์œ„ ํŒŒ์ผ) ์ƒ์„ฑ((.js ํŒŒ์ผ๋กœ ์ƒ์„ฑ) ๊ฒฝ๋กœ ์˜ˆ์‹œ) src/store/slices/.js ํ˜น์€ src/store/modules/.js

    // src/store/slices/list.js
    
    import { createSlice } from "@reduxjs/toolkit";
    
    // 'list' ์ƒํƒœ๊ด€๋ฆฌ slice ์ƒ์„ฑ ๋ฐ ์„ค์ •
    const list = createSlice({
      name: 'list', // silce ๋ช…
      initialState: { // ์ƒํƒœ ๊ด€๋ฆฌํ•  state๋ฅผ ์ •์˜ํ•˜๋Š” ์—ญ์—ญ
        cnt: 0,
      },
      reducers: { // state์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” actions๋ฅผ ์ •์˜ํ•˜๋Š” ์—ญ์—ญ
        addCnt(state) { // state: initialState์˜์—ญ
          state.cnt += 1;
        }, 
        minusCnt(state) {
          state.cnt -= 1;
        },
        changeCnt(state, action) {
          // state: 'initialState'์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ
          // action: ์™ธ๋ถ€์—์„œ ์ „๋‹ฌ ๋œ ๊ฐ’์„ ๋‹ด๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ
          //    >action.payload: ์ „๋‹ฌ๋œ ๊ฐ’์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ
          state.cnt = action.payload;
        },
      }
    });
    
    // ์ •์˜ํ•œ Actions ๋‚ด๋ณด๋‚ด๊ธฐ
    // ์ปดํฌ๋„ŒํŠธ์—์„œ ํ˜ธ์ถœ
    export  const {addCnt, minusCnt, changeCnt}  = list.actions;
    
    // Reducer ๋‚ด๋ณด๋‚ด๊ธฐ
    // Store์—์„œ ํ˜ธ์ถœ
    export default list.reducer;
    
  4. ์ƒ์„ฑํ•œ Slices๋ฅผ Store์— ์ถ”๊ฐ€

    // src/store/store.js
    
    import { configureStore } from "@reduxjs/toolkit";
    import listReducer from "./slices/list.js";
    
    // Redux Store ์ƒ์„ฑ ๋ฐ ์„ค์ •
    export default configureStore({
      reducer: {
        list: listReducer,
      }
    });
    
  5. main.jsx์— React Redux <Provider> ์ถ”๊ฐ€ (StrctMode๋ฅผ ์ œ์™ธํ•œ ์น˜์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์ผ ๊ฒƒ)

    // main.jsx
    
    import { StrictMode } from 'react';
    import { createRoot } from 'react-dom/client';
    import App from './App.jsx';
    import { Provider } from 'react-redux';
    import store from './store/store.js';
    
    createRoot(document.getElementById('root')).render(
      <StrictMode>
        <Provider store={store}>
          <App />
        </Provider>
      </StrictMode>
    );
    
  6. ๋“ฑ๋กํ•œ Redux ์‚ฌ์šฉ

    // List.jsx
    
    import { useDispatch, useSelector } from 'react-redux';
    import './List.css';
    import { addCnt, minusCnt } from '../store/slices/list';
    
    function List() {
      // State์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•
      // state๋Š” store์ด๊ธฐ ๋•Œ๋ฌธ์— slice ๋ช…๋„ ํ•จ๊ป˜ ์ ์–ด ์ ‘๊ทผํ•จ
      const cnt = useSelector(state => state.list.cnt); 
    
      // action ํ˜ธ์ถœ ๋ฐฉ๋ฒ•
      const dispatch = useDispatch();
    
      return (
        <>
          <h1>๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€</h1>
          <p>{cnt}</p>
          <button type="button" onClick={() => { dispatch(minusCnt()) }}>-</button>
          <button type="button" onClick={() => { dispatch(addCnt()) }}>+</button>
        </>
      );
    }
    
    export default List;
    
    // App.jsx
    
    import './App.css';
    import List from './components/List.jsx';
    
    function App() {
      return (
        <>
          <List></List>
        </>
      )
    }
    
    export default App;
    

input์˜ value๊ฐ€ string์œผ๋กœ ์ €์žฅ๋จ