reducer
This commit is contained in:
parent
81049e375f
commit
bf344fc561
|
@ -1,3 +1,6 @@
|
|||
import { ReducersMapObject } from 'redux';
|
||||
import signInReducer from '@overflow/member/redux/reducer/signIn';
|
||||
|
||||
// Container Configuration
|
||||
export interface ContainerConfig {
|
||||
placeholderID: string;
|
||||
|
@ -14,16 +17,35 @@ const rpcConfig: RPCConfig = {
|
|||
url: 'ws://127.0.0.1:18081/rpc',
|
||||
};
|
||||
|
||||
// Redux Configuration
|
||||
export interface ReduxConfig {
|
||||
state: ReduxState;
|
||||
reducerMaps: ReducersMapObject[];
|
||||
}
|
||||
export interface ReduxState {
|
||||
|
||||
}
|
||||
const reduxState: ReduxState = {};
|
||||
|
||||
const reduxConfig: ReduxConfig = {
|
||||
state: reduxState,
|
||||
reducerMaps: [
|
||||
signInReducer,
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
// Configuration
|
||||
export interface Config {
|
||||
container: ContainerConfig;
|
||||
rpc: RPCConfig;
|
||||
redux: ReduxConfig;
|
||||
}
|
||||
|
||||
const config: Config = {
|
||||
container: containerConfig,
|
||||
rpc: rpcConfig,
|
||||
redux: reduxConfig,
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -1,10 +1,36 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { Provider, Store } from 'react-redux';
|
||||
import { ConnectedRouter } from 'react-router-redux';
|
||||
import createSagaMiddleware, { SagaMiddleware } from 'redux-saga';
|
||||
import { History } from 'history';
|
||||
import { AppContainer } from 'react-hot-loader';
|
||||
import {
|
||||
applyMiddleware,
|
||||
compose,
|
||||
createStore,
|
||||
GenericStoreEnhancer,
|
||||
Middleware,
|
||||
Store,
|
||||
} from 'redux';
|
||||
|
||||
import {
|
||||
Provider,
|
||||
} from 'react-redux';
|
||||
|
||||
import {
|
||||
ConnectedRouter,
|
||||
routerMiddleware,
|
||||
} from 'react-router-redux';
|
||||
|
||||
import createSagaMiddleware, {
|
||||
SagaMiddleware,
|
||||
} from 'redux-saga';
|
||||
|
||||
import {
|
||||
createHashHistory,
|
||||
History,
|
||||
} from 'history';
|
||||
|
||||
import {
|
||||
AppContainer,
|
||||
} from 'react-hot-loader';
|
||||
|
||||
|
||||
import * as injectTapEventPlugin from 'react-tap-event-plugin';
|
||||
|
||||
|
@ -12,12 +38,9 @@ import Platform from '@overflow/commons/platform';
|
|||
import AppContext from '@overflow/commons/context';
|
||||
import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle';
|
||||
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
|
||||
import ReducerManager from '@overflow/commons/redux/ReducerManager';
|
||||
import ReducerContext from '@overflow/commons/redux/ReducerContext';
|
||||
|
||||
|
||||
import { store, sagaMiddleware, history } from './redux/store';
|
||||
|
||||
import appConfig, { Config } from './config';
|
||||
import appConfig, { Config, ReduxState } from './config';
|
||||
|
||||
import sagas from './redux/saga';
|
||||
// import routes from './router';
|
||||
|
@ -26,9 +49,13 @@ import App from './views/App';
|
|||
|
||||
injectTapEventPlugin();
|
||||
|
||||
const isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
|
||||
// const isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
|
||||
// const useReduxDevTools = window.devToolsExtension && !isProduction ? true : false;
|
||||
|
||||
class Application {
|
||||
private static isProduction:boolean = process.env.NODE_ENV === 'production' ? true : false;
|
||||
private static useReduxDevTools:boolean = window.devToolsExtension && !Application.isProduction ? true : false;
|
||||
|
||||
private config: Config;
|
||||
private container: HTMLElement;
|
||||
private context: AppContext;
|
||||
|
@ -36,14 +63,11 @@ class Application {
|
|||
private store: Store<any>;
|
||||
private sagaMiddleware: SagaMiddleware<any>;
|
||||
private history: History;
|
||||
private reducerManager: ReducerManager;
|
||||
|
||||
|
||||
public constructor() {
|
||||
this.config = appConfig;
|
||||
this.sagaMiddleware = sagaMiddleware;
|
||||
this.store = store;
|
||||
this.history = history;
|
||||
this.reducerManager = new ReducerManager();
|
||||
this.history = createHashHistory();
|
||||
}
|
||||
|
||||
public static Run(): void {
|
||||
|
@ -58,7 +82,8 @@ class Application {
|
|||
|
||||
this.context = await this.initContext();
|
||||
// this.rpcClient = await this.initRpcClient();
|
||||
await this.initSagaEffect();
|
||||
|
||||
await this.initRedux();
|
||||
|
||||
this.store.dispatch(AppContextLifecycleActions.initialized());
|
||||
|
||||
|
@ -97,21 +122,30 @@ class Application {
|
|||
const init = new Promise<void>(resolve => {
|
||||
// state tree
|
||||
// reducer
|
||||
for (let reducerMap of this.config.redux.reducerMaps) {
|
||||
ReducerContext.putReducers(reducerMap);
|
||||
}
|
||||
// middleware
|
||||
let middlewares: Middleware[] = new Array();
|
||||
this.sagaMiddleware = createSagaMiddleware();
|
||||
middlewares.push(this.sagaMiddleware);
|
||||
|
||||
let routerReduxMiddleware = routerMiddleware(this.history);
|
||||
middlewares.push(routerReduxMiddleware);
|
||||
|
||||
// store
|
||||
let middleware: GenericStoreEnhancer = applyMiddleware(...middlewares);
|
||||
this.store = createStore(
|
||||
ReducerContext.reducer,
|
||||
this.config.redux.state,
|
||||
Application.useReduxDevTools ? compose(middleware, window.devToolsExtension()) : middleware,
|
||||
);
|
||||
// saga
|
||||
|
||||
});
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
private initSagaEffect(): Promise<void> {
|
||||
const rpcClient = new Promise<void>(resolve => {
|
||||
this.sagaMiddleware.run(sagas);
|
||||
resolve();
|
||||
});
|
||||
|
||||
return rpcClient;
|
||||
return init;
|
||||
}
|
||||
|
||||
private displayLoading(): void {
|
||||
|
@ -148,7 +182,7 @@ class Application {
|
|||
|
||||
|
||||
private displayApp(): void {
|
||||
isProduction ? this.displayProductionApp() : this.displayDebugApp();
|
||||
Application.isProduction ? this.displayProductionApp() : this.displayDebugApp();
|
||||
}
|
||||
private displayProductionApp(): void {
|
||||
ReactDOM.render(
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { Action, combineReducers } from 'redux';
|
||||
import State from '../state';
|
||||
|
||||
import { reducer as signinReducer} from '@overflow/member/redux/reducer/signIn';
|
||||
import { reducer as signoutReducer} from '@overflow/member/redux/reducer/signOut';
|
||||
import { reducer as signupReducer} from '@overflow/member/redux/reducer/signUp';
|
||||
|
||||
import { ConnectedRouter } from 'react-router-redux';
|
||||
|
||||
|
||||
const reducer = combineReducers<State>({
|
||||
signinReducer,
|
||||
signoutReducer,
|
||||
signupReducer,
|
||||
});
|
||||
|
||||
export default reducer;
|
|
@ -1,5 +0,0 @@
|
|||
interface State {
|
||||
|
||||
}
|
||||
|
||||
export default State;
|
|
@ -1,47 +0,0 @@
|
|||
import {
|
||||
applyMiddleware,
|
||||
compose,
|
||||
createStore,
|
||||
Store,
|
||||
} from 'redux';
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
import createSagaMiddleware, {
|
||||
SagaMiddleware,
|
||||
} from 'redux-saga';
|
||||
|
||||
import {
|
||||
createHashHistory,
|
||||
History,
|
||||
} from 'history';
|
||||
|
||||
import {
|
||||
EnhancerOptions,
|
||||
composeWithDevTools,
|
||||
} from 'redux-devtools-extension/logOnlyInProduction';
|
||||
|
||||
import reducer from './reducer';
|
||||
import State from './state';
|
||||
|
||||
const useReduxDevTools = window.devToolsExtension && process.env.NODE_ENV !== 'production' ? true : false;
|
||||
|
||||
|
||||
const history = createHashHistory();
|
||||
const sagaMiddleware: SagaMiddleware<any> = createSagaMiddleware();
|
||||
const middlewares = [sagaMiddleware, routerMiddleware(history)];
|
||||
|
||||
const store: Store<State> = createStore<State>(
|
||||
reducer,
|
||||
useReduxDevTools ?
|
||||
compose(
|
||||
applyMiddleware(...middlewares),
|
||||
window.devToolsExtension(),
|
||||
)
|
||||
:
|
||||
applyMiddleware(...middlewares),
|
||||
);
|
||||
|
||||
export {
|
||||
history,
|
||||
sagaMiddleware,
|
||||
store,
|
||||
};
|
|
@ -2,55 +2,59 @@ import Action from './Action';
|
|||
import * as Redux from 'redux';
|
||||
|
||||
interface ReducerItem<State> {
|
||||
initialState: State;
|
||||
reducer: Redux.Reducer<State>;
|
||||
}
|
||||
|
||||
class ReducerManager {
|
||||
class ReducerContext {
|
||||
private static instance: ReducerContext = new ReducerContext();
|
||||
private reducerMap: Map<string, ReducerItem<any>[]>;
|
||||
|
||||
public constructor() {
|
||||
private constructor() {
|
||||
this.reducerMap = new Map();
|
||||
}
|
||||
|
||||
public putReducer<State>(type: string, initialState: State, reducer: Redux.Reducer<State>): void {
|
||||
public static getInstance(): ReducerContext {
|
||||
return ReducerContext.instance;
|
||||
}
|
||||
|
||||
public static putReducers(handlers: Redux.ReducersMapObject): void {
|
||||
for(let type in handlers) {
|
||||
if (handlers.hasOwnProperty(type)) {
|
||||
ReducerContext.getInstance().putReducer(type, handlers[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static reducer<State, A extends Action>(state: State, action: A): State {
|
||||
const actionType = action.type;
|
||||
if (ReducerContext.getInstance().reducerMap.has(actionType)) {
|
||||
let reducerItems = ReducerContext.getInstance().reducerMap.get(actionType);
|
||||
for (let reducerItem of reducerItems) {
|
||||
let reducer = reducerItem.reducer;
|
||||
state = reducer(state, action);
|
||||
}
|
||||
} else {
|
||||
console.log(`Reducer for [${actionType}] is not exist in the context.`);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private putReducer<State>(type: string, reducer: Redux.Reducer<State>): void {
|
||||
let reducerItems: ReducerItem<any>[];
|
||||
if (!this.reducerMap.has(type)) {
|
||||
reducerItems = new Array();
|
||||
this.reducerMap.set(type, reducerItems);
|
||||
} else {
|
||||
reducerItems = this.reducerMap.get(type);
|
||||
console.log(`Count of reducer[${type}] is ${reducerItems.length + 1}`);
|
||||
}
|
||||
let reducerItem: ReducerItem<State> = {
|
||||
initialState: initialState,
|
||||
reducer: reducer,
|
||||
};
|
||||
|
||||
reducerItems.push(reducerItem);
|
||||
}
|
||||
|
||||
public putReducers<State>(initialState: State, handlers: Redux.ReducersMapObject): void {
|
||||
for(let type in handlers) {
|
||||
if (handlers.hasOwnProperty(type)) {
|
||||
this.putReducer(type, initialState, handlers[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public reducer<State, A extends Action>(state: State, action: A): State {
|
||||
const actionType = action.type;
|
||||
if (this.reducerMap.has(actionType)) {
|
||||
let reducerItems = this.reducerMap.get(actionType);
|
||||
for (let reducerItem of reducerItems) {
|
||||
let initialState = reducerItem.initialState;
|
||||
let reducer = reducerItem.reducer;
|
||||
state = reducer(state, action);
|
||||
}
|
||||
} else {
|
||||
console.log(`Reducer for [${actionType}] is not loaded.`);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default ReducerManager;
|
||||
export default ReducerContext;
|
|
@ -1,21 +1,32 @@
|
|||
import Action from '@overflow/commons/redux/Action';
|
||||
import { ReducersMapObject } from 'redux';
|
||||
import createReducer from '@overflow/commons/redux/createReducer';
|
||||
import Member from '@overflow/member/api/model/Member';
|
||||
|
||||
import * as SigninActionTypes from '../action/signIn';
|
||||
import SigninState, { defaultState as signinDefaultState } from '../state/SignIn';
|
||||
|
||||
export type reducer = (state: SigninState, action: Action<Member | Error>) => SigninState;
|
||||
// export type reducer = (state: SigninState, action: Action<Member | Error>) => SigninState;
|
||||
|
||||
export const reducer: reducer = createReducer(signinDefaultState, {
|
||||
[SigninActionTypes.REQUEST_SUCCESS]: (state: SigninState, action: Action<Member>): SigninState => {
|
||||
// export const reducer: reducer = createReducer(signinDefaultState, {
|
||||
// [SigninActionTypes.REQUEST_SUCCESS]: (state: SigninState = signinDefaultState, action: Action<Member>): SigninState => {
|
||||
// return state;
|
||||
// },
|
||||
// [SigninActionTypes.REQUEST_FAILURE]: (state: SigninState = signinDefaultState, action: Action<Error>): SigninState => {
|
||||
// return state;
|
||||
// },
|
||||
// });
|
||||
|
||||
const reducer: ReducersMapObject = {
|
||||
[SigninActionTypes.REQUEST_SUCCESS]: (state: SigninState = signinDefaultState, action: Action<Member>): SigninState => {
|
||||
return state;
|
||||
},
|
||||
[SigninActionTypes.REQUEST_FAILURE]: (state: SigninState, action: Action<Error>): SigninState => {
|
||||
[SigninActionTypes.REQUEST_FAILURE]: (state: SigninState = signinDefaultState, action: Action<Error>): SigninState => {
|
||||
return state;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default reducer;
|
||||
|
||||
// export const reducer: reducer = (state: SigninState = signinDefaultState, action: Action<Member | Error>): SigninState => {
|
||||
// switch (action.type) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user