1

TLDR: My problem is: useState in the context is not re-rendering in time for useContext from another component to get the updated state values.

If you don't want to read the full explanation, a brief explanation of the 3 hooks in different components would be very much appreciated too. Thanks!

TokenProvider: context

TeeToken, AccessToken, IdToken, and RefreshToken: view components that display context

App.js

<TokenProvider>
  <TeeToken />
  <AccessToken />
  <IdToken />
  <RefreshToken />
  ...
</TokenProvider>

TokenProvider.js

import React, { useState, useEffect } from 'react';
import TokenContext from '../shared/TokenContext';

const TokenProvider = ({ children }) => {
  const [teeToken, setTeeToken] = useState('');
  const [accessToken, setAccessToken] = useState('');
  const [idToken, setIdToken] = useState('');
  const [refreshToken, setRefreshToken] = useState('');
  const [tokens, setTokens] = useState('');
  // for data fetching logic
  const [responseData, setResponseData] = useState('');
  const [uniqueId, setUniqueId] = useState('');

  const loadToken = () => {
    const { oauth } = responseData;
    setUniqueId(responseData.reduxRequestId);
    setTeeToken(oauth.teeToken);
    setAccessToken({ decoded: jwt.decode(oauth.accessToken), encoded: oauth.accessToken });
    setIdToken({ decoded: jwt.decode(oauth.idToken), encoded: oauth.idToken });
    setRefreshToken(oauth.refreshToken);
  };

  if (responseData) {
    if (uniqueId !== responseData.reduxRequestId) {
      loadToken();
    }
  }

  useEffect(() => {
    setTokens({ teeToken, accessToken, idToken, refreshToken });
  }, [teeToken]);

  const context = {
    tokens,
    setResponseData,
  }
  return <TokenContext.Provider value={context}>{children}</TokenContext.Provider>;
};

export default TokenProvider;

I omitted a lot of the fetching part of the code for the sake of this question, but the point is I use useState to set all TeeToken, AccessToken, IdToken, and RefreshToken constant values from the fetched data and put them all nicely into tokens. Tokens is then put into the context.

I'm using useEffect because putting useState of tokens can not get the updated versions of all the various tokens because useState is an asynchronous action. So I'm waiting for the component to re-render, then tokens can get all the various updated values and re-render again to update the context.

However, the other component that uses useContext gets the un-updated version of the tokens. Please help how I could make the other component get the updated version of the tokens! Thanks.

EDIT: technically my issue can be solved by just passing all various tokens into context instead of keeping it in tokens, but I would still appreciate it if somebody could give me an explanation on the React Hooks lifecycle

Jpark9061
  • 924
  • 3
  • 11
  • 26
  • Where does the `fetchedInfoX` values come from? That's a big thing. You should update your question with the asynchronous handling code. – Fábio Batista Jul 02 '20 at 22:21
  • @Fábio Batista It comes from the context as well. I've updated the code, thanks for the heads up – Jpark9061 Jul 02 '20 at 22:39

0 Answers0