I'm searching for a clean way to store my access token in React.
After a bit of research, I found that using a global variable is a working "cheat" to obtain what I want. However, I was guessing if there was a clearer way to get the same result.
//token.js
const access_token= "";
export const setAccessToken(token){
access_token=token;
}
export const getAccessToken(){
return access_token;
}
//NOTICE:
// -ON LOGIN/REFRESH: I set the access token
// -ON API CALLS: I get the access token and I add it to the header
api.js
const baseURL= "http://my_base_url";
const generateApiInterface = ()=>{
let headers : any= {
};
token=getAccessToken(); //HERE I NEED TO RETRIEVE MY ACCESS TOKEN
if(token){
headers={
'Authorization': 'Token '+ token,
...headers //append other basic proprieties
}
}
return axios.create({
baseURL: baseURL,
headers: headers
});
}
const api = generateApiInterface();
The way you're doing it is preferable to keep anything in memory. If this is server side, then you'd want to make sure you delete the token once you're done, but if not then the current approach is desirable. Note, you're using a const, you'd want to change that to a let. Another idea would be to use session storage, but then that brings the idea of XSS.
However, React provide a way to have "global" state - this would be to use a provider and context. Here's an example:
// provider.tsx
import React, { useContext, createContext, FC, useState } from 'react'
type AccessTokenContext = [string, React.Dispatch<React.SetStateAction<string>>]
const AccessTokenProvider: FC = (props) => {
const [accessToken, setAccessToken] = useState<string>(null)
return <AccessToken.Provider value={[accessToken, setAccessToken]} {...props} />
}
const AccessToken = createContext<AccessTokenContext>(null)
const useAccessToken = (): AccessTokenContext => useContext<AccessTokenContext>(AccessToken)
export { AccessTokenProvider, useAccessToken }
You'd have to wrap your app container in AccessTokenProvider:
// index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { AccessTokenProvider } from './providers/AccessTokenProvider'
ReactDOM.render(
<AccessTokenProvider>
<App />
</AccessTokenProvider>,
document.getElementById('app')
)
Then you can then use the hook useAccessToken in App and any children of App. Of course, this provider doesn't have to be root level, but it's easiest to include it here.
// app.tsx
import React, { FC } from 'react'
const App: FC = props => {
const [accessToken, setAccessToken] = useAccessToken()
return <div>{/* content */}</div>
}
export default App
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With