jshuaf / Aquaforces

The land of the free
0 stars 0 forks source link

Use one persistent store across pages #85

Closed ssneilss closed 7 years ago

ssneilss commented 7 years ago

Just some suggestions about the redux part. This is what our architecture looks like

2016-08-25 6 00 54

in case for example some information in "console" should also be used in "game"

Its our code:

store.js

import { createStore, applyMiddleware, compose, combineReducers} from 'redux'
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
import reducers from '../reducers/index'
import callAPImiddleware from '../middlewares/callAPImiddleware' // it's our customized middleware
import { Iterable } from 'immutable' // we used immutable js

export default function configureStore(initialState, options){
  const logger = options? options.logger : true
  let middlewares = [callAPImiddleware, thunkMiddleware]
  if (process.env.NODE_ENV === 'development' && logger) {
    const stateTransformer = (state) => {
      if (Iterable.isIterable(state)) return state.toJS()
      else return state
    }
    middlewares.push(createLogger({ stateTransformer }))
  }
  const createStoreWithMiddleware = compose(
    applyMiddleware(...middlewares)
  )(createStore)
  const store = createStoreWithMiddleware(reducers, initialState)

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextRootReducer = require('../reducers')
      store.replaceReducer(nextRootReducer)
    })
  }
  return store
}

export const store = configureStore()

reducers/index.js

import { combineReducers } from 'redux-immutable' // you can just use redux 
import general from './general.reducer'
import event from './event.reducer'
import user from './user.reducer'
import free_point from './free_point.reducer'
import order from './order.reducer'

const rootReducer = combineReducers({
  general: general,
  event: event,
  user: user,
  free_point: free_point,
  order: order
})

export default rootReducer

reducers/general.reducer.js

import * as actionTypes from '../constants/user.const'
import Immutable from 'immutable'

export const initialState = Immutable.fromJS({
  current_user: {
    id: null,
    name: null,
    selfie: null,
  },
  inviter: null,
})

export default (state = initialState, action) => {
  switch (action.type) {

    // get general data for user
    case actionTypes.SET_USER_GENERAL: {
      return state
        .updateIn(['current_user', 'name'], () => action.data.name || null)
        .updateIn(['current_user', 'id'], () => action.data.id || null)
        .updateIn(['current_user', 'selfie'], () => action.data.selfie || null)
    }

    // set inviter infos
    case actionTypes.SET_INVITER: {
      const inviterData = Immutable.fromJS(action.data)
      return state.update('inviter', () => inviterData)
    }

    default:
      return state
  }
}
jshuaf commented 7 years ago

Sorry, I don't quite get what's different than ours. Apart from the middleware, it looks very similar to what we have now. Are you saying that we should use one persistent Redux store across pages?

ssneilss commented 7 years ago

yeah we combined all the reducers into one big reducer

it's also useful for us because we have routing on client side (without reload all the data in store will be persistent when user's location goes back and forth)

just an idea! you can think about it and use your own!

jshuaf commented 7 years ago

Yeah I'm working on react-router right now.

jshuaf commented 7 years ago

Not sure if I'd want to share a store between the question console and the game host, however... as there won't be much overlap

alexandernext commented 7 years ago

@jshuaf yeah we should consider that too

jshuaf commented 7 years ago

Putting this on hold for now.