useAuth.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { useContext, useEffect, useMemo, useRef } from 'react';
  2. import {
  3. AuthContext,
  4. AuthState,
  5. RequiredUserInfo,
  6. } from '@app/contexts/AuthContext';
  7. import { TOKEN_KEY, USERINFO_KEY } from '@app/constants';
  8. import {
  9. removeAllItems,
  10. saveAllItems,
  11. saveItem,
  12. } from '@common/StorageHelper.ts';
  13. const useAuth = (): {
  14. state: AuthState;
  15. actions: {
  16. login: (token: string, userInfo: RequiredUserInfo) => Promise<void>;
  17. logout: () => Promise<void>;
  18. update: (userInfo: RequiredUserInfo) => Promise<void>;
  19. };
  20. } => {
  21. const context = useContext(AuthContext);
  22. if (!context) {
  23. throw new Error('useAuth must be used in AuthProvider!');
  24. }
  25. const contextRef = useRef(context);
  26. useEffect(() => {
  27. contextRef.current = context;
  28. }, [context]);
  29. const authActions = useMemo(
  30. () => ({
  31. login: async (token: string, userInfo: RequiredUserInfo) => {
  32. await saveAllItems([
  33. { key: TOKEN_KEY, data: token },
  34. { key: USERINFO_KEY, data: JSON.stringify(userInfo) },
  35. ]);
  36. contextRef.current.dispatch({
  37. type: 'login',
  38. payload: {
  39. token: token,
  40. userInfo: userInfo,
  41. },
  42. });
  43. },
  44. logout: async () => {
  45. await removeAllItems([TOKEN_KEY, USERINFO_KEY]);
  46. contextRef.current.dispatch({
  47. type: 'logout',
  48. payload: undefined,
  49. });
  50. },
  51. update: async (userInfo: RequiredUserInfo) => {
  52. await saveItem(USERINFO_KEY, JSON.stringify(userInfo));
  53. contextRef.current.dispatch({ type: 'update', payload: userInfo });
  54. },
  55. }),
  56. [],
  57. );
  58. return { state: context.state, actions: authActions };
  59. };
  60. export { useAuth };