Skip to content

Instantly share code, notes, and snippets.

@ProfAvery
Last active October 8, 2024 17:42
Show Gist options
  • Save ProfAvery/ccace6ffc6810d5749faab561fa0a090 to your computer and use it in GitHub Desktop.
Save ProfAvery/ccace6ffc6810d5749faab561fa0a090 to your computer and use it in GitHub Desktop.
Redux without React - Summer 2024 AMSE Bootcamp
import { createStore } from 'redux';
const initialCartState = [];
const CartTypes = {
ADD: 'ADD',
EMPTY: 'EMPTY',
REMOVE: 'REMOVE',
};
const findItem = (cart, itemId) => cart.find((item) => item.itemId === itemId);
const cartReducer = (state = initialCartState, action) => {
switch (action.type) {
case CartTypes.ADD:
if (findItem(state, action.itemId)) {
return state.map((item) => (item.itemId === action.itemId
? { ...item, quantity: item.quantity + 1 }
: item));
}
return [
...state,
{ itemId: action.itemId, quantity: 1 },
];
case CartTypes.EMPTY:
return [];
case CartTypes.REMOVE:
return state.filter((item) => item.itemId !== action.itemId);
default:
// throw new Error(`Invalid action type ${action.type}`);
return state;
}
};
const store = createStore(cartReducer);
console.log.count = 0;
store.subscribe(() => { console.log('State', console.log.count++, ':', store.getState()) });
console.log('Filling cart...');
store.dispatch({ type: CartTypes.ADD, itemId: 'coffee' });
store.dispatch({ type: CartTypes.ADD, itemId: 'coffee' });
store.dispatch({ type: CartTypes.ADD, itemId: 'cookie' });
console.log("\nMaybe I don't need a cookie...");
store.dispatch({ type: CartTypes.REMOVE, itemId: 'cookie' });
console.log('\nNever mind...')
store.dispatch({ type: CartTypes.EMPTY });
import { createStore, combineReducers } from 'redux';
const initialUserState = { 'authenticated': false };
const UserTypes = {
LOGIN: 'LOGIN',
LOGOUT: 'LOGOUT',
};
const userReducer = (state = initialUserState, action) => {
switch (action.type) {
case UserTypes.LOGIN:
if (action.username && action.password === 'pass') {
return { username: action.username, authenticated: true };
}
return { authenticated: false };
case UserTypes.LOGOUT:
return { authenticated: false };
default:
return state;
}
}
const initialCartState = [];
const CartTypes = {
ADD: 'ADD',
EMPTY: 'EMPTY',
REMOVE: 'REMOVE',
};
const findItem = (cart, itemId) => cart.find((item) => item.itemId === itemId);
const cartReducer = (state = initialCartState, action) => {
switch (action.type) {
case CartTypes.ADD:
if (findItem(state, action.itemId)) {
return state.map((item) => (item.itemId === action.itemId
? { ...item, quantity: item.quantity + 1 }
: item));
}
return [
...state,
{ itemId: action.itemId, quantity: 1 },
];
case CartTypes.EMPTY:
return [];
case CartTypes.REMOVE:
return state.filter((item) => item.itemId !== action.itemId);
default:
// throw new Error(`Invalid action type ${action.type}`);
return state;
}
};
const rootReducer = combineReducers({
user: userReducer,
cart: cartReducer,
});
const store = createStore(rootReducer);
console.log.count = 0;
store.subscribe(() => { console.log('State', console.log.count++, ':', store.getState()) });
console.log('Filling cart...');
store.dispatch({ type: CartTypes.ADD, itemId: 'coffee' });
store.dispatch({ type: CartTypes.ADD, itemId: 'coffee' });
store.dispatch({ type: CartTypes.ADD, itemId: 'cookie' });
console.log('\nLogging in with wrong password...');
store.dispatch({ type: UserTypes.LOGIN, username: 'ProfAvery', password: 'wrong' });
console.log('\nLogging in...');
store.dispatch({ type: UserTypes.LOGIN, username: 'ProfAvery', password: 'pass' });
console.log("\nMaybe I don't need a cookie...");
store.dispatch({ type: CartTypes.REMOVE, itemId: 'cookie' });
console.log('\nNever mind...')
store.dispatch({ type: CartTypes.EMPTY });
console.log('\nLogging out...');
store.dispatch({ type: UserTypes.LOGOUT });
import { createSlice, configureStore } from '@reduxjs/toolkit'
const userSlice = createSlice({
name: 'user',
initialState: { authenticated: false },
reducers: {
login: (state, action) => {
if (action.payload.username && action.payload.password === 'pass') {
state.username = action.payload.username;
state.authenticated = true;
}
state.authenticated = false;
},
logout: (state) => {
delete state.username;
state.authenticated = false;
}
}
});
const { login, logout } = userSlice.actions;
const findItem = (cart, itemId) => cart.find((item) => item.itemId === itemId);
const cartSlice = createSlice({
name: 'cart',
initialState: [],
reducers: {
add: (state, action) => {
const item = findItem(state, action.payload.itemId);
if (item) {
item.quantity++;
} else {
state.push({ itemId: action.payload.itemId, quantity: 1 });
}
},
empty: (state) => {
state.length = 0;
},
remove: (state, action) => {
const index = state.findIndex((item) => item.itemId === action.payload.itemId);
if (index !== -1) {
state.splice(index, 1);
}
},
},
});
const { add, empty, remove } = cartSlice.actions;
const store = configureStore({
reducer: {
user: userSlice.reducer,
cart: cartSlice.reducer,
},
});
console.log.count = 0;
store.subscribe(() => { console.log('State', console.log.count++, ':', store.getState()) });
console.log('Filling cart...');
store.dispatch(add({ itemId: 'coffee' }));
store.dispatch(add({ itemId: 'coffee' }));
store.dispatch(add({ itemId: 'cookie' }));
console.log('\nLogging in with wrong password...');
store.dispatch(login({ username: 'ProfAvery', password: 'wrong' }));
console.log('\nLogging in...');
store.dispatch(login({ username: 'ProfAvery', password: 'pass' }));
console.log("\nMaybe I don't need a cookie...");
store.dispatch(remove({ itemId: 'cookie' }));
console.log('\nNever mind...')
store.dispatch(empty());
console.log('\nLogging out...');
store.dispatch(logout());
{
"dependencies": {
"@reduxjs/toolkit": "^2.2.6",
"redux": "^5.0.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment