I am creating login/logout/fogotpass logic with JSON WEB TOKEN and The API Context in my react project.
I am having a problem with typescript with value error in my <AuthContext.Provider value={contextValue}>
Not sure how I should set the types here.
import React, { useState, useEffect, useCallback } from "react";
type ContextObj = {
token: string | null | undefined;
isLoggedIn: any;
login: (token: string, expirationTime: any) => void;
logout: () => void;
};
let logoutTimer: any;
const AuthContext = React.createContext({
token: "",
isLoggedIn: false,
login: (token: any) => {},
logout: () => {},
});
const calculateRemainingTime = (expirationTime: any) => {
const currentTime = new Date().getTime();
const adjExpirationTime = new Date(expirationTime).getTime();
const remainingDuration = adjExpirationTime - currentTime;
return remainingDuration;
};
const retrieveStoredToken = () => {
const storedToken = localStorage.getItem("token");
const storedExpirationDate = localStorage.getItem("expirationTime");
const remainingTime = calculateRemainingTime(storedExpirationDate);
if (remainingTime <= 3600) {
localStorage.removeItem("token");
localStorage.removeItem("expirationTime");
return null;
}
return {
token: storedToken,
duration: remainingTime,
};
};
export const AuthContextProvider = (props: any) => {
const tokenData = retrieveStoredToken();
let initialToken;
if (tokenData) {
initialToken = tokenData.token;
}
const [token, setToken] = useState(initialToken);
const userIsLoggedIn = !!token;
const logoutHandler = useCallback(() => {
setToken(null);
localStorage.removeItem("token");
localStorage.removeItem("expirationTime");
if (logoutTimer) {
clearTimeout(logoutTimer);
}
}, []);
const loginHandler = (token: string, expirationTime: any) => {
setToken(token);
localStorage.setItem("token", token);
localStorage.setItem("expirationTime", expirationTime);
const remainingTime = calculateRemainingTime(expirationTime);
logoutTimer = setTimeout(logoutHandler, remainingTime);
};
useEffect(() => {
if (tokenData) {
console.log(tokenData.duration);
logoutTimer = setTimeout(logoutHandler, tokenData.duration);
}
}, [tokenData, logoutHandler]);
const contextValue: ContextObj = {
token: token,
isLoggedIn: userIsLoggedIn,
login: loginHandler,
logout: logoutHandler,
};
return (
<AuthContext.Provider value={contextValue}>
{props.children}
</AuthContext.Provider>
);
};
export default AuthContext;
CodePudding user response:
you've forgotten about adding expirationTime
in your creating context login key function argument part.
your contextType:
type ContextObj = {
token: string ; //change this too
isLoggedIn: any; //change this to boolean too
login: (token: string, expirationTime: any) => void;
logout: () => void;
};
your context
const AuthContext = React.createContext({
token: "",
isLoggedIn: false,
login: (token , expirationTime) => {}, //adding expirationTime
logout: () => {},
});
CodePudding user response:
You have a type issue with your token, which can be null. But currently, you didn't specified it, so you should do it this way:
const [token, setToken] = useState<string|undefined|null>(initialToken);
By default, if you don't specify it, the type would be only string or undefined