I'm trying to create a useAuth custom hook within React 17 and Typescript. The solution that I have is kind of working, but it requires the following when accessing the hook methods:
const auth = useAuth();
// Do other stuff
const result = await auth?.login(data);
The issue is that I need to use the ?
operator when calling the login
method, as the auth
object can be null.
The reason for this I know is how I have implemented in the context, however I can't figure out how in TypeScript to create the context with a null context object by default (i.e. no currentUser).
This is how I've currently implemented the hook:
interface AuthProvider {
children: ReactNode;
}
interface ProvideAuthContext {
currentUser: AppUser | null,
login: (loginInfo: LoginInfo) => Promise<LoginResponse>,
register: (registerInfo: RegisterInfo) => Promise<RegisterResponse>
}
const authContext = createContext<ProvideAuthContext | null>(null);
export function ProvideAuth({ children }: AuthProvider) {
const auth = useProvideAuth();
return <authContext.Provider value={auth}>{children}</authContext.Provider>
}
// Hook for child components to get the auth object and re-render when it changes.
export const useAuth = () => {
return useContext(authContext);
};
// Provider hook that creates auth object and handles state
function useProvideAuth() {
// This is where I implement the ProvideAuthContext interface
// Return the user object and auth methods
return {
currentUser,
login,
register
};
}
Any help with this would be amazing. I'm 99% sure it's got to do with this line:
const authContext = createContext<ProvideAuthContext | null>(null);
.
I can't do it this way: const authContext = createContext<ProvideAuthContext | null>({ currentUser: null });
as I get the following error:
Argument of type '{ currentUser: null; }' is not assignable to parameter of type 'ProvideAuthContext'. Type '{ currentUser: null; }' is missing the following properties from type 'ProvideAuthContext': login, register
I can't change the ProvideAuthContext
login and register methods to be login?:... or register?:...
as I can't then use them in components that use the useAuth hook.
Thanks, Justin