RnMultibundler/src/app/contexts/AuthContext.tsx

119 行
2.8 KiB
TypeScript

import React, { createContext, ReactNode, useEffect, useReducer } from 'react';
import { TOKEN_KEY, UserInfo, USERINFO_KEY } from '@app/constants';
import { getAllItems, storageApp } from '@common/StorageHelper.ts';
type RequiredUserInfo = Required<UserInfo>;
type AuthState = {
loading: boolean;
token?: string; // token
userInfo?: RequiredUserInfo; // 用户信息
};
type ActionMap = {
retrieve: { token: string; userInfo: RequiredUserInfo } | undefined; // 应用启动取回本地缓存
login: { token: string; userInfo: RequiredUserInfo }; // 登录
logout: undefined; // 退出登录
update: RequiredUserInfo; // 更新用户信息
};
type Action = {
[Key in keyof ActionMap]: {
type: Key;
payload: ActionMap[Key];
};
}[keyof ActionMap];
function reducer(state: AuthState, action: Action): AuthState {
switch (action.type) {
case 'retrieve':
return {
...state,
loading: false,
token: action.payload?.token,
userInfo: action.payload?.userInfo,
};
case 'login':
return {
...state,
loading: false,
token: action.payload.token,
userInfo: action.payload.userInfo,
};
case 'logout':
return {
...state,
loading: false,
token: undefined,
userInfo: undefined,
};
case 'update':
return {
...state,
loading: false,
userInfo: action.payload,
};
}
}
const initialState = {
loading: true,
token: undefined,
userInfo: undefined,
};
const AuthContext = createContext<
| {
state: AuthState;
dispatch: React.Dispatch<Action>;
}
| undefined
>(undefined);
const AuthProvider = ({ children }: { children: ReactNode }) => {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
async function retrieve() {
try {
const values = await getAllItems([
{ key: TOKEN_KEY },
{ key: USERINFO_KEY },
]);
if (values[0][1] && values[1][1]) {
const tokenValue = values[0][1];
const userInfoValue = JSON.parse(values[1][1]);
dispatch({
type: 'retrieve',
payload: {
token: tokenValue,
userInfo: { ...userInfoValue, isFirstLogin: false },
},
});
} else {
dispatch({
type: 'retrieve',
payload: undefined,
});
}
} catch {
dispatch({
type: 'retrieve',
payload: undefined,
});
}
}
retrieve();
}, []);
return (
<AuthContext.Provider value={{ state, dispatch }}>
{children}
</AuthContext.Provider>
);
};
export type { AuthState, RequiredUserInfo };
export { AuthContext, AuthProvider };