ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

728x90

*์„ค์น˜ :

ํˆดํ‚ท

npm install @reduxjs/toolkit react-redux

 

์ผ๋ฐ˜

 npm install redux@4.1.2 react-redux

*์„ธํŒ…(1) : store.js ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์ฝ”๋“œ ๋ณต๋ถ™

import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: { }
})

*์„ธํŒ…(2) : index.js ํŒŒ์ผ๋กœ ๊ฐ€์„œ Provider๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ์— import, ๊ทธ๋ฆฌ๊ณ  ๋ฐ‘์— <Provider store={importํ•ด์˜จ๊ฑฐ}> ์ด๊ฑธ๋กœ <App/> ์„ ๊ฐ์‹ธ์ค€๋‹ค.

import { Provider } from "react-redux";
import store from './store.js'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
);

๋ฆฌ๋•์Šค ?

๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๊ตฐ๋ฐ ๋ชฐ์•„๋„ฃ๊ณ , ์—ฌ๊ธฐ์ €๊ธฐ์—์„œ ๊บผ๋‚ด๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

์šฉ์–ด

  • Action 
    • ๐Ÿ‘‰ ์ƒํƒœ์— ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•  ๋•Œ(=๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ) ์“ด๋‹ค. 
    • dispatch ์‚ฌ์šฉํ• ๋•Œ () ์•ˆ์— ์•ก์…˜๊ฐ์ฒด๋ฅผ ๋„ฃ์„๋•Œ ํ•„์š”
     // ์•ก์…˜์€ ๊ฐ์ฒด์˜ˆ์š”. ์ด๋Ÿฐ ์‹์œผ๋กœ ์“ฐ์ธ๋‹ค. type์€ ์ด๋ฆ„๊ฐ™์€๊ฑฐ! ์ €ํฌ๊ฐ€ ์ •ํ•˜๋Š” ์ž„์˜์˜ ๋ฌธ์ž์—ด์„ ๋„ฃ๋Š”๋‹ค
        {type: 'CHANGE_STATE', data: {...}}
  •  ActionCreator
    • ๐Ÿ‘‰ ์ƒํƒœ์— ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•  ๋•Œ(=๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ) ์“ด๋‹ค. 
const PLUS_ONE = "PLUS_ONE"; // value๋Š” ์ƒ์ˆ˜๋กœ ์ƒ์„ฑ

// ์•ก์…˜๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ์ƒ์„ฑ
// export ๊ฐ€ ๋ถ™๋Š” ์ด์œ ๋Š” plusOne()๋Š” ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€์„œ ์‚ฌ์šฉ๋  ์˜ˆ์ •์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
export const plusOne = () => { 
  return {
    type: PLUS_ONE, // type์—๋Š” ์œ„์—์„œ ๋งŒ๋“  ์ƒ์ˆ˜๋กœ ์‚ฌ์šฉ (vscode์—์„œ ์ž๋™์™„์„ฑ ์ง€์›)
  };
};

// ๋ฆฌ๋“€์„œ
const counter = (state = initialState, action) => {
  switch (action.type) {
    case PLUS_ONE: // case์—์„œ๋„ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ, ์œ„์—์„œ ์„ ์–ธํ•œ ์ƒ์ˆ˜๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 
      return {
        number: state.number + 1,
      };
    case MINUS_ONE: // case์—์„œ๋„ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ, ์œ„์—์„œ ์„ ์–ธํ•œ ์ƒ์ˆ˜๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 
      return {
        number: state.number - 1,
      };
    default:
      return state;
  }
};
  • Reducer 
    • ๐Ÿ‘‰ ๋ฆฌ๋•์Šค์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜ 
    • ์•ก์…˜ ์ƒ์„ฑ ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ฆ„ > ์•ก์…˜์„ ๋งŒ๋“ฌ > ๋ฆฌ๋“€์„œ๊ฐ€ ํ˜„์žฌ ๋ฐ์ดํ„ฐ์™€ ์•ก์…˜ ๊ฐ์ฒด๋ฅผ ๋ฐ›์Œ > ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ฌ > ๋ฆฌํ„ด
    // ๊ธฐ๋ณธ ์ƒํƒœ๊ฐ’์„ ์ž„์˜๋กœ ์ •ํ•ด์คฌ์–ด์š”.
    const initialState = {
    	name: 'woo0'
    }
    
    function reducer(state = initialState, action) {
    	switch(action.type){
    
    		// action์˜ ํƒ€์ž…๋งˆ๋‹ค ์ผ€์ด์Šค๋ฌธ์„ ๊ฑธ์–ด์ฃผ๋ฉด, 
    		// ์•ก์…˜์— ๋”ฐ๋ผ์„œ ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋Œ๋ ค์คŒ
    		case CHANGE_STATE: 
    			return {name: 'woo1'};
    
    		default: 
    			return false;
    	}	
    }
  • Store
    • ๐Ÿ‘‰ ์Šคํ† ์–ด์—๋Š” ๋ฆฌ๋“€์„œ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ๋ฆฌ๋•์Šค์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ , ์•ก์…˜์„ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ๋‚ด์žฅ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ ๋จ
  • useDispatch
    • ๐Ÿ‘‰  ์•ก์…˜ ๊ฐ์ฒด ๋ณด๋‚ผ๋•Œ ์“ฐ๋Š” ํ•จ์ˆ˜
// src/App.js

import React from "react";
import { useDispatch } from "react-redux"; /1/ import ํ•ด์ฃผ์„ธ์š”.

const App = () => {
  const dispatch = useDispatch(); /2/ dispatch ์ƒ์„ฑ
  return (
    <div>
      <button
				/3/ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€
        onClick={() => {
					// ๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ dispatch๊ฐ€ ์‹คํ–‰๋˜๊ณ , ()์•ˆ์— ์žˆ๋Š” ์•ก์…˜๊ฐ์ฒด๊ฐ€ ๋ฆฌ๋“€์„œ๋กœ ์ „๋‹ฌ๋œ๋‹ค.
          dispatch({ type: "PLUS_ONE" }); 
        }}
      >
				+ 1
      </button>
    </div>
  • useSelector 
    • ๐Ÿ‘‰ ์ปดํฌ๋„ŒํŠธ์— ์Šคํ† ์–ด๋ฅผ ์กฐํšŒ ํ• ๋•Œ ์“ฐ๋Š” ํ•จ์ˆ˜ 
  • payload
    • ์•ก์…˜๊ฐ์ฒด์— ๋ชฉ์ ์–ด๋„ ๊ฐ™์ด ๋‹ด์•„ ๋ณด๋‚ด์ฃผ๋Š” ๊ฒƒ
  • Duck ๊ตฌ์กฐ 

์˜ˆ์‹œ ) 

const ADD_NUBER = 'ADD_NUMBER';
const MINUS_NUMBER = 'MINUS_NUMBER';

export const addNumber = (payload) => {
  return {
    type: ADD_NUBER,
    payload,
  };
};

export const minusNumber = (payload) => {
  return {
    type: MINUS_NUMBER,
    payload,
  };
};

const initialState = {
  number: 0,
};

const counter = (state = initialState, action) => {
  switch (action.type) {
    case ADD_NUBER:
      return {
        number: state.number + action.payload,
      };

    case MINUS_NUMBER:
      return {
        number: state.number - action.payload,
      };

    default:
      return state;
  }
};

export default counter;
import React from 'react';
import { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addNumber, minusNumber } from './redux/modules/counter';

const Redux = () => {
  const dispatch = useDispatch();
  const [number, setNumber] = useState(0);
  const globalNumber = useSelector((state) => state.counter.number);

  const onChangeHandler = (e) => {
    const { value } = e.target;
    setNumber(+value);
  };
  const onClickAddNumberHandler = () => {
    dispatch(addNumber(number));
  };

  const onClickMinusNumberHandler = () => {
    dispatch(minusNumber(number));
  };
  console.log(number);
  return (
    <div>
      <div>{globalNumber}</div>
      <input type="number" onChange={onChangeHandler} />
      <button onClick={onClickAddNumberHandler}>๋”ํ•˜๊ธฐ</button>
      <button onClick={onClickMinusNumberHandler}>๋นผ๊ธฐ</button>
    </div>
  );
};

export default Redux;

 

728x90

'๐Ÿ“Frontend > ๐Ÿ“˜React' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[React] Redux-toolkit ์„ค์น˜ ๋ฐ ์„ธํŒ…  (0) 2022.08.06
[React] Router ?  (0) 2022.07.30
[React] onChange  (0) 2022.07.26
[React] Mapํ•จ์ˆ˜  (0) 2022.07.26
[React] ๋ชจ๋‹ฌ์ฐฝ(์‚ผํ•ญ ์—ฐ์‚ฐ์ž)  (0) 2022.07.26
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
ยซ   2025/09   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
๊ธ€ ๋ณด๊ด€ํ•จ