Browse Source

[refactor] useContext and useReducer instead Redux

RoyLiu 5 years ago
parent
commit
e778048309

+ 8 - 5
actions/index.ts

@@ -1,7 +1,10 @@
-import * as types from '../constants/actionTypes';
+import { Dispatch } from 'react';
+import pdfActions from './pdf';
+import mainActions from './main';
 
-export const switchNavbar = (state: string) => ({ type: types.SWITCH_NAVBAR, payload: { state }});
+const useActions = (dispatch: Dispatch<any>) => ({
+  ...pdfActions(dispatch),
+  ...mainActions(dispatch),
+});
 
-export const switchSidebar = (state: string) => ({ type: types.SWITCH_SIDEBAR, payload: { state }});
-
-export default {};
+export default useActions;

+ 6 - 0
actions/main.ts

@@ -0,0 +1,6 @@
+import * as types from '../constants/actionTypes';
+
+export default (dispatch: any) => ({
+  switchNavbar: (state: string) => dispatch({ type: types.SWITCH_NAVBAR, payload: { state }}),
+  switchSidebar: (state: string) => dispatch({ type: types.SWITCH_SIDEBAR, payload: { state }}),
+});

+ 12 - 0
actions/pdf.ts

@@ -0,0 +1,12 @@
+import * as types from '../constants/actionTypes';
+import { ProgressType, ViewportType} from '../constants/type';
+
+export default (dispatch: any) => ({
+  setTotalPage: (page: number) => dispatch({ type: types.SET_TOTAL_PAGE, payload: page }),
+  setCurrentPage: (page: number) => dispatch({ type: types.SET_CURRENT_PAGE, payload: page }),
+  setPdf: (pdf: Object) => dispatch({ type: types.SET_PDF, payload: pdf }),
+  setProgress: (progress: ProgressType) => dispatch({ type: types.SET_PROGRESS, payload: progress }),
+  setViewport: (viewport: ViewportType) => dispatch({ type: types.SET_VIEWPORT, payload: viewport }),
+  changeScale: (scale: number | string) => dispatch({ type: types.CHANGE_SCALE, payload: scale }),
+  changeRotate: (rotation: number) => dispatch({ type: types.CHANGE_ROTATE, payload: rotation }),
+})

+ 8 - 0
constants/actionTypes.ts

@@ -1,2 +1,10 @@
 export const SWITCH_NAVBAR = 'SWITCH_NAVBAR';
 export const SWITCH_SIDEBAR = 'SWITCH_SIDEBAR';
+
+export const SET_CURRENT_PAGE = 'SET_CURRENT_PAGE';
+export const SET_TOTAL_PAGE = 'SET_TOTAL_PAGE';
+export const SET_PDF = 'SET_PDF';
+export const SET_PROGRESS = 'SET_PROGRESS';
+export const SET_VIEWPORT = 'SET_VIEWPORT';
+export const CHANGE_SCALE = 'CHANGE_SCALE';
+export const CHANGE_ROTATE = 'CHANGE_ROTATE';

+ 28 - 0
constants/type.ts

@@ -0,0 +1,28 @@
+export type TypeRenderingStates = 'RENDERING' | 'LOADING' | 'FINISHED' | 'PAUSED';
+
+export type PayloadType = {
+  payload: any;
+};
+
+export type ViewportType = {
+  width: number;
+  height: number;
+};
+
+export type ProgressType = {
+  loaded: number;
+  total: number;
+};
+
+export type ScrollStateType = {
+  right: boolean;
+  down: boolean;
+  lastX: number;
+  lastY: number;
+};
+
+export type SelectOptionType = {
+  key: string | number;
+  content: React.ReactNode;
+  value: number | string;
+};

+ 13 - 0
middleware/index.ts

@@ -0,0 +1,13 @@
+import { Dispatch } from 'react';
+
+// import { SET_CURRENT_PAGE } from '../constants/actionTypes';
+
+const applyMiddleware = (dispatch: Dispatch<any>) => (action: { type: string, payload?: any }) => {
+  dispatch(action);
+
+  // if (action.type === SET_CURRENT_PAGE) {
+  //   dispatch({type: UPDATE_RENDERING_QUEUE, payload: []});
+  // }
+};
+
+export default applyMiddleware;

+ 1 - 3
pages/_app.js

@@ -4,8 +4,6 @@ import { SnackbarProvider } from 'notistack';
 import loadable from '@loadable/component';
 import { i18n, appWithTranslation } from '../i18n';
 import { StoreProvider } from '../store';
-import reducers from '../reducers';
-import initialState from '../store/initialState';
 
 const GlobalStyle = loadable(() => import('../global/styled'));
 
@@ -27,7 +25,7 @@ class MainApp extends App {
     } = this.props;
 
     return (
-      <StoreProvider initialState={initialState} reducer={reducers}>
+      <StoreProvider>
         <SnackbarProvider maxSnack={3}>
           <GlobalStyle lang={i18n.language} />
           <Component {...pageProps} />

+ 12 - 3
reducers/index.ts

@@ -1,4 +1,5 @@
-import * as actions from './main';
+import * as mainActions from './main';
+import * as pdfActions from './pdf';
 import * as types from '../constants/actionTypes';
 
 const createReducer = (handlers: {[key: string]: any}) => (state: Object, action: { type: string }) => {
@@ -10,6 +11,14 @@ const createReducer = (handlers: {[key: string]: any}) => (state: Object, action
 };
 
 export default createReducer({
-  [types.SWITCH_NAVBAR]: actions.navbarState,
-  [types.SWITCH_SIDEBAR]: actions.sidebarState,
+  [types.SWITCH_NAVBAR]: mainActions.setNavbarState,
+  [types.SWITCH_SIDEBAR]: mainActions.setSidebarState,
+
+  [types.SET_CURRENT_PAGE]: pdfActions.setCurrentPage,
+  [types.SET_TOTAL_PAGE]: pdfActions.setTotalPage,
+  [types.SET_PDF]: pdfActions.setPdf,
+  [types.SET_PROGRESS]: pdfActions.setProgress,
+  [types.SET_VIEWPORT]: pdfActions.setViewport,
+  [types.CHANGE_SCALE]: pdfActions.changeScale,
+  [types.CHANGE_ROTATE]: pdfActions.changeRotate,
 });

+ 3 - 5
reducers/main.ts

@@ -1,13 +1,11 @@
-type Payload = {
-  payload: any;
-};
+import { PayloadType } from '../constants/type';
 
-export const navbarState = (state: Object, { payload }: Payload) => ({
+export const setNavbarState = (state: Object, { payload }: PayloadType) => ({
   ...state,
   navbarState: payload.state,
 });
 
-export const sidebarState = (state: Object, { payload }: Payload) => ({
+export const setSidebarState = (state: Object, { payload }: PayloadType) => ({
   ...state,
   sidebarState: payload.state,
 });

+ 36 - 0
reducers/pdf.ts

@@ -0,0 +1,36 @@
+import { PayloadType } from '../constants/type';
+
+export const setCurrentPage = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  currentPage: payload,
+});
+
+export const setTotalPage = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  totalPage: payload,
+});
+
+export const setPdf = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  pdf: payload,
+});
+
+export const setProgress = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  progress: payload,
+});
+
+export const setViewport = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  viewport: payload,
+});
+
+export const changeScale = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  scale: payload,
+});
+
+export const changeRotate = (state: Object, { payload }: PayloadType) => ({
+  ...state,
+  rotation: payload,
+});

+ 27 - 15
store/index.tsx

@@ -1,27 +1,39 @@
-import React, { createContext, useContext, useReducer, Reducer } from 'react';
+import React, { createContext, useContext, useReducer } from 'react';
 
-import { StateType } from '../store/initialState';
+import initialMainState, { StateType as MainStateType } from './initialMainState';
+import initialPdfState, { StateType as PdfStateType } from './initialPdfState';
+
+import reducers from '../reducers'
+import applyMiddleware from '../middleware';
+
+type StateType = MainStateType & PdfStateType
 
 type IContextProps = [
   StateType,
   ({type}:{type:string}) => void,
 ]
 
+export const initialState = {
+  ...initialMainState,
+  ...initialPdfState
+};
+
 export const StateContext = createContext({} as IContextProps);
 
 export const StoreProvider = ({
-  reducer,
-  initialState,
   children,
-}: {
-  reducer: Reducer<any, any>;
-  initialState: StateType;
+} : {
   children: React.ReactNode;
-}) => (
-  <StateContext.Provider
-    value={useReducer(reducer, initialState)}
-    children={children}
-  />
-);
-
-export const useStore = () => useContext(StateContext);
+}) => {
+  const [state, dispatch] = useReducer(reducers, initialState);
+  const enhancedDispatch = applyMiddleware(dispatch);
+
+  return (
+    <StateContext.Provider
+      value={[state, enhancedDispatch]}
+      children={children}
+    />
+  );
+};
+
+export default () => useContext(StateContext);

store/initialState.ts → store/initialMainState.ts


+ 21 - 0
store/initialPdfState.ts

@@ -0,0 +1,21 @@
+import { ProgressType, ViewportType  } from '../constants/type';
+
+export type StateType = {
+  totalPage: number;
+  currentPage: number;
+  pdf: any;
+  progress: ProgressType;
+  viewport: ViewportType,
+  scale: number;
+  rotation: number;
+};
+
+export default {
+  totalPage: 1,
+  currentPage: 1,
+  pdf: null,
+  progress: {},
+  viewport: {},
+  scale: 1,
+  rotation: 0,
+};