dispatch(함수) → 함수실행 → 함수안에서 dispatch(객체)
📁 index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "./redux/config/configStore";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
reportWebVitals();
📁 App.jsx
import logo from "./logo.svg";
import "./App.css";
import { useDispatch, useSelector } from "react-redux";
import { addNumber, minusNumber } from "./redux/modules/counter";
import { useState } from "react";
function App() {
const globalNumber = useSelector((state) => state.counter.number);
const [number, setNumber] = useState(0);
const dispatch = useDispatch();
const onPlusButtonclickHandler = () => {
dispatch(addNumber(+number));
};
const onMinusButtonClickHandler = () => {
dispatch(minusNumber(+number));
};
return (
<div>
<div>{globalNumber}</div>
<input
type="number"
onChange={(e) => {
setNumber(e.target.value);
}}
/>
<br />
<button onClick={onPlusButtonclickHandler}>더하기</button>
<button onClick={onMinusButtonClickHandler}>빼기</button>
</div>
);
}
export default App;
📁 redux / config / configStore.js
import counter from "../modules/counter";
const { configureStore } = require("@reduxjs/toolkit");
const store = configureStore({
reducer: {
counter: counter,
}
})
export default store;
📁 redux / modules / counter.js
import { createSlice } from "@reduxjs/toolkit"
// 초기 상태(state)
const initialState = {
number: 0
}
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
addNumber: (state, action) => {
state.number = state.number + action.payload
},
minusNumber: (state, action) => {
state.number = state.number - action.payload
}
}
});
export default counterSlice.reducer
export const {addNumber, minusNumber} = counterSlice.actions
📁 redux / modules / counter.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
//2개의 input
// (1) 이름 : 의미는 크게 없음
// (2) 함수
export const __addNumber = createAsyncThunk(
"ADD_NUMBER_WAIT",
(payload, thunkAPI) => {
// 수행하고 싶은 동작 : 3초 기다리게 할 예정
setTimeout(() => {
thunkAPI.dispatch(addNumber(payload));
}, 3000);
}
);
export const __minusNumber = createAsyncThunk(
"MINUS_NUMBER_WAIT",
(payload, thunkAPI) => {
// 수행하고 싶은 동작 : 3초 기다리게 할 예정
setTimeout(() => {
thunkAPI.dispatch(minusNumber(payload));
}, 3000);
}
);
// 초기 상태(state)
const initialState = {
number: 0,
};
const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
addNumber: (state, action) => {
state.number = state.number + action.payload;
},
minusNumber: (state, action) => {
state.number = state.number - action.payload;
},
},
});
export default counterSlice.reducer;
export const { addNumber, minusNumber } = counterSlice.actions;
📁 App.jsx
import "./App.css";
import { useDispatch, useSelector } from "react-redux";
import { useState } from "react";
import { __addNumber, __minusNumber } from "./redux/modules/counter"; // 추가
function App() {
const globalNumber = useSelector((state) => state.counter.number);
const [number, setNumber] = useState(0);
const dispatch = useDispatch();
const onPlusButtonclickHandler = () => {
dispatch(__addNumber(+number)); // 수정
};
const onMinusButtonClickHandler = () => {
dispatch(__minusNumber(+number)); // 수정
};
return (
<div>
<div>{globalNumber}</div>
<input
type="number"
onChange={(e) => {
setNumber(e.target.value);
}}
/>
<br />
<button onClick={onPlusButtonclickHandler}>더하기</button>
<button onClick={onMinusButtonClickHandler}>빼기</button>
</div>
);
}
export default App;
리덕스 미들웨어를 사용하면, 액션이 리듀서로 전달되기 전에 중간에 어떤 작업을 더 할수 있다.