I've the following project structure(roughly),
src/
index.tsx -> entry point for React
App.tsx
client.tsx -> Apollo client definition
components/
TokenProvider.tsx -> Provider for accessToken
index.tsx looks like following, it provides apollo-client and the accessToken to whole App.
import React from "react";
import { render } from "react-dom";
import { ApolloProvider } from "@apollo/client";
import { TokenProvider } from "./components/TokenContext";
import client from "./client";
import App from "./App";
render(
<ApolloProvider client={client}>
<TokenProvider>
<App />
</TokenProvider>
</ApolloProvider>,
document.getElementById("root")
);
client.tsx looks like following,
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";
const httpLink = new HttpLink({
uri: "http://localhost:4000",
credentials: "include",
});
const client = new ApolloClient({
cache: new InMemoryCache(),
link: httpLink,
});
export default client;
I am trying to do some authorization stuff so I need to add authorization header to the HttpLink in client.tsx.
So in index.tsx, I need something like the following,
// in index.tsx
const httpLink = new HttpLink({
uri: "http://localhost:4000",
credentials: "include",
headers: {
authorization: `bearer ${accessToken}`, // I need this <---
},
});
The problem is, accessToken variable can be accessed through useContext API, because it is provided by a React Context. But client.tsx is not a React component so I cannot access it.
I set accessToken either in user login or in the beginning of the App if there is refresh token available. So in App.tsx,
// in App.tsx
useEffect(() => {
// prevent login in every refresh
refreshAccessToken().then((accessToken) => {
// dispatch comes from `TokenProvider`
dispatch({ type: CHANGE_TOKEN, payload: { accessToken } });
});
}, [])
Is there any way to overcome this? Maybe I shouldn't provide accessToken with Context API, what are the other solutions?