-
-
Notifications
You must be signed in to change notification settings - Fork 66
Refactor state mgmt #1326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Refactor state mgmt #1326
Changes from 11 commits
99e178f
d8ec068
8d7f9b5
6734394
46964b6
c28c2c5
0daa051
e96c414
083d8ba
88d46da
c7a34b0
8345a80
4befaf5
2234a97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| const readAndDeleteFromLocalStorage = (key, defaultValue) => { | ||
| const val = localStorage[key]; | ||
|
||
| if (!val) { | ||
| return defaultValue; | ||
| } | ||
|
|
||
| try { | ||
| return JSON.parse(val); | ||
| } catch (e) { | ||
| return defaultValue; | ||
| } finally { | ||
| delete localStorage[key]; | ||
| } | ||
| }; | ||
|
|
||
| export default function migrateState(initialState, migratedState) { | ||
| const ret = {}; | ||
| if (!migratedState) { | ||
| migratedState = {}; | ||
| } | ||
| for (const property in initialState) { | ||
| ret[property] = readAndDeleteFromLocalStorage( | ||
| property, | ||
| migratedState[property] == undefined | ||
| ? initialState[property] | ||
| : migratedState[property] | ||
| ); | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { createSlice } from "@reduxjs/toolkit"; | ||
|
|
||
| export const timers = ["Fast", "Moderate", "Slow", "Leisurely"]; | ||
|
|
||
| export const initialState = { | ||
| addBots: true, | ||
| shufflePlayers: true, | ||
| useTimer: true, | ||
| timerLength: "Moderate", // Fast Moderate or Slow | ||
| }; | ||
|
|
||
| const startControls = createSlice({ | ||
| name: "startControls", | ||
| initialState, | ||
| reducers: { | ||
| toggleBots: state => { | ||
| state.addBots = !state.addBots; | ||
| }, | ||
| toggleShufflePlayers: state => { | ||
| state.shufflePlayers = !state.shufflePlayers; | ||
| }, | ||
| toggleUseTimer: state => { | ||
| state.useTimer = !state.useTimer; | ||
| }, | ||
| setTimerLength: (state, action) => { | ||
| if (timers.includes(action.payload)) { | ||
| state.timerLength = action.payload; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These reducers are what we could easily write tests over. Haven't seen this createSlice thing before but we just need a way to reach in and check those reduce functions. These ones are simple, but would be good to get into habit of putting tests over ones which have multiple paths over them. I would say we should have a testing pattern in place before merging this. Would set us up well. Happy to help |
||
|
|
||
| export const selectAddBots = state => state.startControls.addBots; | ||
| export const selectShufflePlayers = state => state.startControls.shufflePlayers; | ||
| export const selectUseTimer = state => state.startControls.useTimer; | ||
| export const selectTimerLength = state => state.startControls.timerLength; | ||
|
|
||
| export const { toggleBots, toggleShufflePlayers, toggleUseTimer, setTimerLength } = startControls.actions; | ||
|
|
||
| export default startControls; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import { combineReducers, configureStore, getDefaultMiddleware } from "@reduxjs/toolkit"; | ||
| import storage from "redux-persist/lib/storage"; | ||
| import { | ||
| persistReducer, FLUSH, | ||
| REHYDRATE, | ||
| PAUSE, | ||
| PERSIST, | ||
| PURGE, | ||
| REGISTER | ||
| } from "redux-persist"; | ||
| import { initialState as startControlInitState } from "./start-controls"; | ||
| import startControls from "./start-controls"; | ||
| import migrateState from "./migration"; | ||
|
|
||
| const reducers = combineReducers({ | ||
| startControls: startControls.reducer | ||
| }); | ||
|
|
||
| const persistConfig = { | ||
| key: "root", | ||
| storage, | ||
| migrate: (state) => { | ||
| if (!state) { | ||
| state = {}; | ||
| } | ||
| const newState = { | ||
| ...state, | ||
| startControls: migrateState(startControlInitState, state.startControls) | ||
| }; | ||
| return Promise.resolve(newState); | ||
| } | ||
| }; | ||
|
|
||
| const persistedReducer = persistReducer(persistConfig, reducers); | ||
|
|
||
| export default configureStore({ | ||
| reducer: persistedReducer, | ||
| devTools: true, | ||
| middleware: getDefaultMiddleware({ | ||
| serializableCheck: { | ||
| ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER] | ||
| } | ||
| }), | ||
| }); |
Uh oh!
There was an error while loading. Please reload this page.