diff --git a/package-lock.json b/package-lock.json index 31535f8..35e280c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.18", "@mui/material": "^5.14.18", + "@reduxjs/toolkit": "^2.0.1", "@tanstack/react-query": "^5.8.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", @@ -19,6 +20,7 @@ "axios": "^1.6.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-redux": "^9.0.2", "react-router-dom": "^6.19.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" @@ -3723,6 +3725,38 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.0.1.tgz", + "integrity": "sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.0", + "redux-thunk": "^3.1.0", + "reselect": "^5.0.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.3.tgz", + "integrity": "sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/@remix-run/router": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.12.0.tgz", @@ -4867,9 +4901,9 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/react": { - "version": "18.2.37", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", - "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", + "version": "18.2.42", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.42.tgz", + "integrity": "sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4877,9 +4911,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.15", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz", - "integrity": "sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==", + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", "dependencies": { "@types/react": "*" } @@ -4968,6 +5002,11 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.6.tgz", "integrity": "sha512-HYtNooPvUY9WAVRBr4u+4Qa9fYD1ze2IUlAD3HoA6oehn1taGwBx3Oa52U4mTslTS+GAExKpaFu39Y5xUEwfjg==" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/ws": { "version": "8.5.9", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", @@ -15292,6 +15331,40 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-redux": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.0.2.tgz", + "integrity": "sha512-34EI42cYZxJF59Iht6RDM5xDun5EdhV8CbJcTe+mYx97XMHLNYA6RrH9r/ZOZX3CetVCYfBEU9oAY9h3sZarsw==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.41", + "@types/react-dom": "^18.2.17", + "react": "^18.0", + "react-dom": "^18.0", + "react-native": ">=0.71", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", @@ -15472,6 +15545,19 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.0.tgz", + "integrity": "sha512-blLIYmYetpZMET6Q6uCY7Jtl/Im5OBldy+vNPauA8vvsdqyt66oep4EUpAMWNHauTC6xa9JuRPhRB72rY82QGA==" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -15617,6 +15703,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/reselect": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.0.1.tgz", + "integrity": "sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -17496,6 +17587,14 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 8c7ccbc..036c957 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.18", "@mui/material": "^5.14.18", + "@reduxjs/toolkit": "^2.0.1", "@tanstack/react-query": "^5.8.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", @@ -14,6 +15,7 @@ "axios": "^1.6.2", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-redux": "^9.0.2", "react-router-dom": "^6.19.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" diff --git a/src/App.js b/src/App.js index 9cd2b18..6b48db5 100644 --- a/src/App.js +++ b/src/App.js @@ -6,6 +6,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Container } from '@mui/material'; import { BrowserRouter as Router, Routes, Route, BrowserRouter} from 'react-router-dom' import Dashboard from 'components/Dashboard'; +import { Counter } from 'components/counterC'; function App() { @@ -19,6 +20,7 @@ function App() { {/* */} } /> + } /> diff --git a/src/components/counterC.js b/src/components/counterC.js new file mode 100644 index 0000000..5e80973 --- /dev/null +++ b/src/components/counterC.js @@ -0,0 +1,29 @@ +import React from 'react' +import { useSelector, useDispatch } from 'react-redux' +import { decrement, increment } from '../redux/slices/counterSlice.js' + +export function Counter() { + // @ts-ignore + const count = useSelector((state) => state.counter.value) + const dispatch = useDispatch() + + return ( +
+
+ + {count} + +
+
+ ) +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index d563c0f..701a723 100644 --- a/src/index.js +++ b/src/index.js @@ -3,11 +3,15 @@ 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/store.js' const root = ReactDOM.createRoot(document.getElementById('root')); root.render( + + ); diff --git a/src/redux/slices/counterSlice.js b/src/redux/slices/counterSlice.js new file mode 100644 index 0000000..4968914 --- /dev/null +++ b/src/redux/slices/counterSlice.js @@ -0,0 +1,24 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const initialState = { + value:0, +} + +export const counterSlice = createSlice({ + name:'counter', + initialState, + reducers:{ + increment:(state)=>{ + state.value+=1 + }, + decrement:(state)=>{ + state.value-=1 + }, + incrementByAmount:(state,action)=>{ + state.value+=action.payload + } + } +}) + +export const {increment, decrement, incrementByAmount} = counterSlice.actions +export default counterSlice.reducer \ No newline at end of file diff --git a/src/redux/store.js b/src/redux/store.js new file mode 100644 index 0000000..b632ab8 --- /dev/null +++ b/src/redux/store.js @@ -0,0 +1,8 @@ +import { configureStore } from '@reduxjs/toolkit' +import counterReducer from './slices/counterSlice' + +export const store = configureStore({ + reducer: { + counter:counterReducer, + }, +}) \ No newline at end of file