Skip to content

Instantly share code, notes, and snippets.

@sp0033212000
Created October 5, 2020 08:53
Show Gist options
  • Save sp0033212000/ed220d8cc4d4bda0163938080ac2e805 to your computer and use it in GitHub Desktop.
Save sp0033212000/ed220d8cc4d4bda0163938080ac2e805 to your computer and use it in GitHub Desktop.
import React, { createContext, Dispatch, useReducer } from "react";
export type DispatchType<S, R = any> = (dispatch: Dispatch<S>) => R;
type ActionType<A extends Action> = {
[key: string]: <T extends any[], R = any>(
...any: T
) => (dispatch: Dispatch<A>) => R;
};
type ReducerType<S, A extends Action> = (state: S, actions: A) => S;
type BoundActionsProps<A extends Action> = {
[key: string]: (action: Action, dispatch: Dispatch<A>) => any;
};
interface Action {
type: string;
payload?: any;
}
export default <S, A extends Action>(
reducer: ReducerType<S, A>,
actions: ActionType<A>,
defaultValue: S
) => {
const Context = createContext<{
state: S;
actions: Record<keyof typeof actions, any>;
} | null>({ state: defaultValue, actions });
const Provider: React.FC = ({ children }) => {
const [state, dispatch] = useReducer<ReducerType<S, A>>(
reducer,
defaultValue
);
const boundActions: BoundActionsProps<A> = {};
Object.keys(actions).forEach((key) => {
boundActions[key] = ((_action, _dispatch) => {
return (...argument: any[]) => _action(...argument)(_dispatch);
})(actions[key], dispatch);
});
return (
<Context.Provider value={{ state, actions: { ...boundActions } }}>
{children}
</Context.Provider>
);
};
return { Context, Provider };
};
import React, { useContext } from "react";
import { PageContext } from "../../context/PageContext";
import PageContainer from "../Genenal/PageContainer/PageContainer";
const PageOne: React.FC = () => {
const {state, actions: {
forwardPage // <= auto refer
} } = useContext(PageContext)!;
return (
<PageContainer zIndex={6}>
<div className="main">
<div className="main__background">
<img
alt="hero"
src={`${require("../../assets/img/hun_p1_main1_img.png")}`}
srcSet={[
`${require("../../assets/img/hun_p1_main1_img.png")} 1x`,
`${require("../../assets/img/hun_p1_main1_img@2x.png")} 2x`,
`${require("../../assets/img/hun_p1_main1_img@3x.png")} 3x`,
].join(", ")}
className={["main__background--img", "main__background--1"].join(
" "
)}
/>
<img
alt="hero"
src={`${require("../../assets/img/hun_p1_main2_img.png")}`}
srcSet={[
`${require("../../assets/img/hun_p1_main2_img.png")} 1x`,
`${require("../../assets/img/hun_p1_main2_img@2x.png")} 2x`,
`${require("../../assets/img/hun_p1_main2_img@3x.png")} 3x`,
].join(", ")}
className={["main__background--img", "main__background--2"].join(
" "
)}
/>
</div>
<div className="main__content">
<h1 className="heading__1 main__heading fadeInContent">
簡單找到
<br />
好客人
</h1>
<p className="main__pg fadeInContent">
會員系統 × 訂單管理 × 數據分析 × 行銷工具
</p>
</div>
</div>
</PageContainer>
);
};
export default PageOne;
import createCusContext, { DispatchType } from "./createCusContext";
export type PageState = {
currentPage: number;
totalPage: number;
};
export enum PageTypesEnums {
FORWARD_PAGE = "FORWARD_PAGE",
BACKWARD_PAGE = "BACKWARD_PAGE",
}
interface ForwardPageInterface {
type: typeof PageTypesEnums.FORWARD_PAGE;
}
interface BackwardPageInterface {
type: typeof PageTypesEnums.BACKWARD_PAGE;
}
type PageActions = ForwardPageInterface | BackwardPageInterface;
const forwardPageActions = () => ({
type: PageTypesEnums.FORWARD_PAGE,
});
const pageReducer = (state: PageState, actions: PageActions) => {
switch (actions.type) {
case PageTypesEnums.FORWARD_PAGE:
return { ...state, currentPage: state.currentPage + 1 };
case PageTypesEnums.BACKWARD_PAGE:
return { ...state, currentPage: state.currentPage - 1 };
default:
return state;
}
};
const forwardPage = (): DispatchType<PageActions> => (dispatch) => {
dispatch(forwardPageActions());
};
export const {
Context: PageContext,
Provider: PageProvider,
} = createCusContext<PageState, PageActions>(
pageReducer,
{ forwardPage }, // I want to refer this key where I import this context
{ currentPage: 1, totalPage: 0 }
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment