users and products store

parent 9267aea6
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"name": "mernstack", "name": "mernstack",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@reduxjs/toolkit": "^2.2.0",
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
"mongodb": "^6.3.0", "mongodb": "^6.3.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-redux": "^9.1.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"typescript": "^4.9.5", "typescript": "^4.9.5",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
...@@ -3350,6 +3352,38 @@ ...@@ -3350,6 +3352,38 @@
} }
} }
}, },
"node_modules/@reduxjs/toolkit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.0.tgz",
"integrity": "sha512-ZvPYKfu4kDnAqPhJ1bsis8QFbiQRz3Q2HxW3tw9tVGusPzYKRG7ju1FA+34PGcwCoemjGGv+f/7fEygcRZIwmA==",
"dependencies": {
"immer": "^10.0.3",
"redux": "^5.0.1",
"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/@rollup/plugin-babel": { "node_modules/@rollup/plugin-babel": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
...@@ -4315,6 +4349,11 @@ ...@@ -4315,6 +4349,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
}, },
"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/webidl-conversions": { "node_modules/@types/webidl-conversions": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
...@@ -14889,6 +14928,32 @@ ...@@ -14889,6 +14928,32 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
}, },
"node_modules/react-redux": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.0.tgz",
"integrity": "sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ==",
"dependencies": {
"@types/use-sync-external-store": "^0.0.3",
"use-sync-external-store": "^1.0.0"
},
"peerDependencies": {
"@types/react": "^18.2.25",
"react": "^18.0",
"react-native": ">=0.69",
"redux": "^5.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"react-native": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
...@@ -15024,6 +15089,19 @@ ...@@ -15024,6 +15089,19 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/redux": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="
},
"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": { "node_modules/reflect.getprototypeof": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz",
...@@ -15171,6 +15249,11 @@ ...@@ -15171,6 +15249,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
}, },
"node_modules/reselect": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz",
"integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg=="
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.8", "version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
...@@ -17111,6 +17194,14 @@ ...@@ -17111,6 +17194,14 @@
"requires-port": "^1.0.0" "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": { "node_modules/util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
......
...@@ -19,20 +19,20 @@ connectToDb((err)=>{ ...@@ -19,20 +19,20 @@ connectToDb((err)=>{
}) })
// app.get('/products', (req, res) => {
// db.collection('products').find().sort({id:-1}).toArray()
// .then(result => {res.send(result)})
// .catch(error => res.status(500).send(error))
// })
app.get('/products', (req, res) => { app.get('/products', (req, res) => {
const pageIndex=parseInt(req.query.p || "0") db.collection('products').find().toArray()
let pageSize=5;
db.collection('products').find().skip(pageIndex*pageSize).limit(pageSize).toArray()
.then(result => {res.send(result)}) .then(result => {res.send(result)})
.catch(error => res.status(500).send(error)) .catch(error => res.status(500).send(error))
}) })
// app.get('/products', (req, res) => {
// const pageIndex=parseInt(req.query.p || "0")
// let pageSize=5;
// db.collection('products').find().skip(pageIndex*pageSize).limit(pageSize).toArray()
// .then(result => {res.send(result)})
// .catch(error => res.status(500).send(error))
// })
app.get('/products/:id', (req, res) => { app.get('/products/:id', (req, res) => {
const Id = Number(req.params.id) const Id = Number(req.params.id)
if(!isNaN(Id)){ if(!isNaN(Id)){
......
import logo from './logo.svg'; import logo from './logo.svg';
import './App.css'; import './App.css';
import Home from './components/Home'; import Home from './components/Home';
import store from './reduxstore/store';
import { Provider } from 'react-redux';
const App=()=> { const App=()=> {
return ( return (
<div className="App"> <div className="App">
<Home/> <Provider store={store}>
<Home/>
</Provider>
</div> </div>
); );
} }
......
import React, { memo, useState } from 'react'; import React, { memo, useCallback, useEffect, useState } from 'react';
import axios from 'axios'; import axios from 'axios';
import { fetchProducts,ProductsStateType } from '../reduxstore/productsSlice';
import { fetchUsers,UsersStateType } from '../reduxstore/usersSlice';
import {useDispatch,useSelector } from 'react-redux';
import { RootState } from '../reduxstore/store';
const Home = memo(() => { const Home = memo(() => {
const dispatch=useDispatch()
const users=useSelector((state:RootState)=> state.users.users)
useEffect(() => {
dispatch(fetchUsers());
dispatch(fetchProducts());
}, []);
const testDispatch=useCallback(()=>{
console.log(users)
},[users])
return ( return (
<div> <div>
Home Home
<button onClick={testDispatch}>CLick</button>
</div> </div>
); );
}); });
......
import { createSlice } from "@reduxjs/toolkit"
const initialState={
numOfCakes:10,
}
const cakeSlice=createSlice({
name:'cake',
initialState,
reducers:{
ordered:(state)=>{
state.numOfCakes--
},
restocked:(state,action)=>{
state.numOfCakes+=action.payload
},
},
})
export default cakeSlice.reducer
export const{ordered,restocked}=cakeSlice.actions
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
type productsStateType = {
loading: boolean;
products: any[];
error: string | undefined;
};
const initialState: productsStateType = {
loading: false,
products: [],
error: ''
};
export const fetchProducts:any= createAsyncThunk('products/fetchProducts', async () => {
return await axios.get('http://localhost:4000/products')
.then(response => response.data);
});
const productsSlice = createSlice({
name: 'products',
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchProducts.pending, (state) => {
state.loading = true;
state.error="pending"
});
builder.addCase(fetchProducts.fulfilled, (state, action) => {
state.loading = false;
state.products = action.payload;
state.error = '';
});
builder.addCase(fetchProducts.rejected, (state, action) => {
state.loading = false;
state.products = [];
state.error = action.error || 'Something went wrong!';
});
}
});
export default productsSlice.reducer;
export type ProductsStateType = ReturnType<typeof productsSlice.reducer>;
import { configureStore } from '@reduxjs/toolkit'
import cartReducer from './cartSlice'
import productsReducer,{ProductsStateType} from './productsSlice'
import usersReducer,{UsersStateType} from './usersSlice'
export type RootState= {
products:ProductsStateType;
cart: any;
users: UsersStateType;
}
const store=configureStore({
reducer:{
products:productsReducer,
cart: cartReducer,
users: usersReducer
},
})
export default store
\ No newline at end of file
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
type usersStateType = {
loading: boolean;
users: any[];
error: string | undefined;
};
const initialState: usersStateType = {
loading: false,
users: [],
error: ''
};
export const fetchUsers:any= createAsyncThunk('users/fetchUsers', async () => {
return await axios.get('http://localhost:4000/users')
.then(response => response.data);
});
const usersSlice = createSlice({
name: 'users',
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchUsers.pending, (state) => {
state.loading = true;
state.error="pending"
});
builder.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.users = action.payload;
state.error = '';
});
builder.addCase(fetchUsers.rejected, (state, action) => {
state.loading = false;
state.users = [];
state.error = action.error || 'Something went wrong!';
});
}
});
export default usersSlice.reducer;
export type UsersStateType = ReturnType<typeof usersSlice.reducer>;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment