index.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import {PAGE_SIZE_LIST} from '@utils';
  2. import {Dispatch, useCallback, useReducer} from 'react';
  3. import {createContext} from 'use-context-selector';
  4. import {useContext} from '..';
  5. export type PageContextState = {
  6. page: number,
  7. pageSize: number,
  8. };
  9. export type PageContextAction = {
  10. type: 'EDIT_PAGE',
  11. payload: Partial<PageContextState>,
  12. } | {
  13. type: 'RESET'
  14. };
  15. export function pageContextInit(options?: {page: number; pageSize: number}): PageContextState {
  16. const {page, pageSize} = options ?? {};
  17. return {page: page ?? 1, pageSize: pageSize ?? Number(PAGE_SIZE_LIST[0])};
  18. }
  19. function pageReduce(state: PageContextState, action: PageContextAction): PageContextState {
  20. const {type} = action;
  21. switch (type) {
  22. case 'EDIT_PAGE': {
  23. return {...state, ...action.payload};
  24. }
  25. case 'RESET':
  26. return pageContextInit();
  27. default:
  28. return state;
  29. }
  30. }
  31. export function usePageContextReducer(options?: {page: number; pageSize: number}) {
  32. return useReducer(pageReduce, pageContextInit(options));
  33. }
  34. export function createPageContext() {
  35. return createContext<[PageContextState, Dispatch<PageContextAction>]>(
  36. [pageContextInit(), () => null],
  37. );
  38. }
  39. export function usePage(context: ReturnType<typeof createPageContext>) {
  40. const [{page, pageSize}, dispatch] = useContext(context);
  41. const onPageChange = useCallback(function(page: number, pageSize: number) {
  42. dispatch({type: 'EDIT_PAGE', payload: {page, pageSize}});
  43. }, [dispatch]);
  44. const onCurrentPageChange = useCallback(function(page: number) {
  45. dispatch({type: 'EDIT_PAGE', payload: {page}});
  46. }, [dispatch]);
  47. return [{page, pageSize}, {onPageChange, onCurrentPageChange}] as const;
  48. }