Hope you’re doing well 🙂
I’ve an “auth.js” file, with an aysnc function to get the userId and then store it in session storage. Here it is:
export let userId = sessionStorage.getItem("userId"); const getUserId = async () => { if (token) { await axios .get(`${baseURL}/auth/user`, { headers: { authorization: token } }) .then(function (response) { const { data } = response; return sessionStorage.setItem("userId", data.userId); }) .catch(function (err) { return undefined; }); } }; getUserId();
Then I access this variable in all components that need it, in order to make other requests. Example in App.js:
useEffect(() => { getActiveGames(); if (token && userId) { getCart(); getWallet(); getWalletPayments(); } }, []);
The problem is that, in the first render, the userId comes null (obviously) and I’m trying different ways to update or even re-render, in order to get the updated value, but nothing seems to work. I know there’s somehow a basic solution for this, but I just can’t figure it out.
It would be awesome if you could help 🙂
Advertisement
Answer
Option 1 :
If you want to know when userId is filled in sessionStorage:- Add
userId
in your component state. - Listen for the
storage
event. See StorageEvent - Add userId as dependency in
useEffect
.
const getUserId = ()=> sessionStorage.getItem("userId"); const [userId, setUserId] = useState(getUserId()); useEffect(() => { const storage = (event) => { if(event.originalEvent.storageArea===sessionStorage){ const data = getUserId(); if(data) setUserId(data); } }; window.addEventListener("storage", storage); return ()=> window.removeEventListener("storage", storage) }, []); useEffect(() => { getActiveGames(); if (token && userId) { getCart(); getWallet(); getWalletPayments(); } }, [userId]);
Option 2:
You can manage the userId
using Context
- In
getUserId
returndata.userId
.
const UserContext = React.createContext(); const UserProvider = ({children}) => { const [userId, setUserId] = useState(null); useEffect(()=> { getUserId() .then(user => setUserId(user)); }, []); return <UserContext.Provider value={userId}> {children} </UserContext.Provider> }
In you App.js
return (<UserProvider> ... </UserProvider)
Using userId from any component in your app:
const userId = useContext(UserContext); useEffect(() => { getActiveGames(); if (token && userId) { getCart(); getWallet(); getWalletPayments(); } }, [userId]);