Resource with createContext?

What is the correct way to return a Resource from a context? If you don't provide an initial value then you get an error when trying to call the undefined returned from the useContext call as a function, but if you provide an initial value of () => {} it seems that the context isn't updated reactively when the value createResource accessor is passed to the value prop of the provider?
3 Replies
theshadowboxers
theshadowboxers10mo ago
const AuthContext = createContext(()=>{});

export function AuthProvider(props: { children: any }) {
const [authState, setAuthState] = createSignal<AuthState>();
const [user] = createResource(authState, getUser);
const memoizedUser = createMemo(() => {
let u = user();
console.log("MEMO", u);
return u;
});

initOkta();
okta.authStateManager.subscribe(authState => {
setAuthState(authState);
});

return (
<AuthContext.Provider value={memoizedUser}>
{props.children}
</AuthContext.Provider>
);
}
const AuthContext = createContext(()=>{});

export function AuthProvider(props: { children: any }) {
const [authState, setAuthState] = createSignal<AuthState>();
const [user] = createResource(authState, getUser);
const memoizedUser = createMemo(() => {
let u = user();
console.log("MEMO", u);
return u;
});

initOkta();
okta.authStateManager.subscribe(authState => {
setAuthState(authState);
});

return (
<AuthContext.Provider value={memoizedUser}>
{props.children}
</AuthContext.Provider>
);
}
REEEEE
REEEEE10mo ago
the value of context isn't reactive, so you'll have to do something like
value={{user: memoizedUser}}
value={{user: memoizedUser}}
and then access it like so
const auth = useContext(AuthContext)

auth.user()
const auth = useContext(AuthContext)

auth.user()
the context could be undefined because the provider might not exist but you can assert it using ! if you know it exists
const auth = useContext(AuthContext)!
const auth = useContext(AuthContext)!
theshadowboxers
theshadowboxers10mo ago
Thank you, this was helpful! Your final comment about the provider not existing yet made the light bulb come on and I realised I was calling useContext in the App component which was also where I had the AuthProvider tag... so it didn't exist when I was calling useContext. Moved AuthProvider to the index.tsx and now the useContext works in App component. Appreciate your help!