Skip to content

Commit

Permalink
✨ Refactor of localstorage. Uses subscribe and a simple function to d…
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlee-dev committed Aug 21, 2019
1 parent fc412e1 commit f9bff4e
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 113 deletions.
112 changes: 12 additions & 100 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,103 +2,18 @@ import React, { useEffect } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { generatePlanets } from './util'
import useLocalStorage from './hooks/useLocalStorage'
import { storePlanets } from './redux/actions/world'
import { setPlanets } from './redux/actions/world'
import ItemTimer from './components/ItemTimer'
import View from './views/View'
import ViewSelector from './components/ViewSelector'
import { setShip } from './redux/actions/ship'

const App = ({
handleGeneratePlanets,
handleStorePlanetsInStore,
handleStoreShipInStore,
planets,
ship
}) => {
const [localStoragePlanets, setlocalStoragePlanets] = useLocalStorage(
'planets',
[]
)
const [localStorageShip, setLocalStorageShip] = useLocalStorage('ship', null)

const handleUpdatingPlanets = planets => {
// * Check to see if planets exist
if (localStoragePlanets.length === 0) {
// * If no planets exist in localStorage, set the planets in localStorage
handleGeneratePlanets(setlocalStoragePlanets)
} else {
// * Planets exist in localStorage
// * Check if planets exist in Redux
if (planets[0]) {
// * Planets exist in Redux
// * Check to see if `planets` exactly matches `localStoragePlanets`
const planetsAndlocalStoragePlanetsMatch = localStoragePlanets.every(
(planet, i) => {
const { items } = planet

let finalReturnValue = true

items.forEach((item, j) => {
if (item !== planets[i].items[j]) {
finalReturnValue = false
}
})

return finalReturnValue
}
)

if (!planetsAndlocalStoragePlanetsMatch) {
// * planets and localStoragePlanets do not match exactly
// * update planets in localStorage to match planets in Redux
setlocalStoragePlanets(planets)
}
} else {
// * Planets do not exist in Redux
// * Store the planets from localStorage in Redux
handleStorePlanetsInStore(localStoragePlanets)
}
}
}

const handleUpdatingShip = ship => {
// * If there is no localStorage ship
if (!localStorageShip) {
// * Set localStorage ship to ship
setLocalStorageShip(ship)
} else {
// * There is a localStorage ship
// * Check to see if they match exactly.
// * Check to see if `planets` exactly matches `localStoragePlanets`
const shipAndLocalStorageShipMatch =
ship.cargo.length === localStorageShip.cargo.length &&
ship.cargo.every((item, i) => {
if (ship.cargo.length !== localStorageShip.cargo.length) {
return false
} else {
return item.id !== localStorageShip.cargo[i].id
}
})

if (!shipAndLocalStorageShipMatch) {
// * ship and localStorage ship do not match
// * update ship in localStorage to match ship in Redux

if (ship.cargo.length > localStorageShip.cargo.length) {
setLocalStorageShip(ship)
} else {
handleStoreShipInStore(localStorageShip)
}
}
}
}

const App = ({ handleSetPlanets, planets }) => {
useEffect(() => {
handleUpdatingPlanets(planets)
handleUpdatingShip(ship)
if (planets.length === 0) {
handleSetPlanets(generatePlanets())
}
// eslint-disable-next-line
}, [planets, ship])
}, [])

return (
<div>
Expand All @@ -115,19 +30,16 @@ const App = ({
}

App.propTypes = {
handleGeneratePlanets: PropTypes.func.isRequired,
handleStorePlanetsInStore: PropTypes.func.isRequired,
handleStoreShipInStore: PropTypes.func.isRequired
handleSetPlanets: PropTypes.func.isRequired,
planets: PropTypes.array.isRequired
}

const mapStateToProps = ({ ship, world }) => ({ planets: world.planets, ship })
const mapStateToProps = ({ world }) => ({
planets: world.planets
})

const mapDispatchToProps = dispatch => ({
handleGeneratePlanets: setlocalStoragePlanets =>
generatePlanets(dispatch, setlocalStoragePlanets),
handleStorePlanetsInStore: localStoragePlanets =>
dispatch(storePlanets(localStoragePlanets)),
handleStoreShipInStore: ship => dispatch(setShip(ship))
handleSetPlanets: planets => dispatch(setPlanets(planets))
})

export default connect(
Expand Down
6 changes: 3 additions & 3 deletions src/redux/actions/world.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// * ACTION TYPES
const STORE_PLANETS = 'STORE_PLANETS'
const SET_TIMER_RUNNING = 'SET_TIMER_RUNNING'
const REMOVE_ITEM = 'REMOVE_ITEM'
const SET_PLANETS = 'SET_PLANETS'

// * ACTION GENERATORS
export const storePlanets = planets => ({
type: STORE_PLANETS,
export const setPlanets = planets => ({
type: SET_PLANETS,
payload: { planets }
})

Expand Down
2 changes: 1 addition & 1 deletion src/redux/reducers/world.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const worldDefaultState = {

export default (state = worldDefaultState, action) => {
switch (action.type) {
case 'STORE_PLANETS':
case 'SET_PLANETS':
const { planets } = action.payload

return { ...state, planets }
Expand Down
22 changes: 21 additions & 1 deletion src/redux/store/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,34 @@ import thunk from 'redux-thunk'
import shipReducer from '../reducers/ship'
import uiReducer from '../reducers/ui'
import worldReducer from '../reducers/world'
import { loadState, saveState } from '../../util'
import throttle from 'lodash/throttle'

const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

export default createStore(
const persistedState = loadState()

const store = createStore(
combineReducers({
ship: shipReducer,
ui: uiReducer,
world: worldReducer
}),
persistedState,
composeEnhancer(applyMiddleware(thunk))
)

store.subscribe(
throttle(() => {
saveState({
ship: store.getState().ship,
ui: store.getState().ui,
world: {
isTimerRunning: false,
planets: store.getState().world.planets
}
})
}, 1000)
)

export default store
31 changes: 23 additions & 8 deletions src/util.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { itemList, planets } from './constants'
import { storePlanets } from './redux/actions/world'
import uuidv4 from 'uuid/v4'

const getPlanetName = () => {
const planet = planets[Math.floor(Math.random() * planets.length)]
return planet
}

/**
* Generates a planet with a name and stores it in Redux.
* @param dispatch
*/
export const generatePlanets = (dispatch, setStoragePlanets) => {
export const generatePlanets = () => {
const planets = []

for (let i = 0; i < 3; i++) {
Expand All @@ -32,6 +27,26 @@ export const generatePlanets = (dispatch, setStoragePlanets) => {
planets.push({ isHomePlanet, items, location, name })
}

dispatch(storePlanets(planets))
setStoragePlanets(planets)
return planets
}

export const loadState = () => {
try {
const serializedState = localStorage.getItem('state')
if (serializedState === null) {
return undefined
}
return JSON.parse(serializedState)
} catch (error) {
console.error(error)
}
}

export const saveState = state => {
try {
const serializedState = JSON.stringify(state)
localStorage.setItem('state', serializedState)
} catch (error) {
console.error(error)
}
}

0 comments on commit f9bff4e

Please sign in to comment.