Sahil Ahuja
Friday, November 11, 2022 at 7:27 PM
I'm getting a StatsigUninitializedError if I don't wait for initialization
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:29 PM
That error should only be thrown if you are checking the value of a gate before the initialization has even started. Are you using the useGate hook outside of the component wrapped by the provider?
Sahil Ahuja
Friday, November 11, 2022 at 7:31 PM
No :confused: it's directly within the component tree wrapped by the provider
Sahil Ahuja
Friday, November 11, 2022 at 7:33 PM
tore (statsig)
Friday, November 11, 2022 at 7:34 PM
Can you share some of your code?
tore (statsig)
Friday, November 11, 2022 at 7:36 PM
Are you using the useGate hook or trying to call checkGate directly?
Sahil Ahuja
Friday, November 11, 2022 at 7:36 PM
I've tried both and same issue
Sahil Ahuja
Friday, November 11, 2022 at 7:36 PM
Will share here:
Sahil Ahuja
Friday, November 11, 2022 at 7:39 PM
I have an App.tsx that's the root of my React Native Project, within that I'm putting my own StatsigProvider
StatsigProvider.tsx:
```import type { FC, ReactNode } from 'react';
import React from 'react';
import env from 'react-native-config';
import DeviceInfo from 'react-native-device-info';
import { StatsigProvider as StatsigDefaultProvider } from 'statsig-react-native';
import { useAuthContext } from '../contexts/AuthContext';
const StatsigProvider: FC<{ children: ReactNode }> = ({ children }) => {
const { userNid, currentUser } = useAuthContext();
return (
<StatsigDefaultProvider
sdkKey={env.STATSIG_API_KEY}
user={{
userID: userNid ?? undefined,
appVersion: DeviceInfo.getBuildNumber().toString(),
custom: {
isInternal: currentUser?.isInternal ?? undefined,
username: currentUser?.username ?? undefined,
},
}}
waitForInitialization={false}
>
{children}
</StatsigDefaultProvider>
);
};
export default StatsigProvider;```
App.tsx:
```const App: FC = () => {
return (
<AuthProvider>
<StatsigProvider>
<MainNavigator />
</StatsigProvider>
</AuthProvider>
);
};```
MainNavigator.tsx:
```
const MainNavigator: FC = () => {
const {value, isLoading } = useGate(StatsigGate.TEST);
console.log(value);
return (
<Stack.Navigator screenOptions={ScreenOptions}>
<Stack.Screen name={NavigatorName.TAB} component={TabNavigator} />
</Stack.Navigator>
);
};
export default MainNavigator;```
tore (statsig)
Friday, November 11, 2022 at 7:41 PM
Which version of the sdk are you using?
Sahil Ahuja
Friday, November 11, 2022 at 7:41 PM
The
https://www.npmjs.com/package/statsig-react-native/v/4.7.2-beta.0|4.7.2-beta.0 version that you very helpfully got working for me yesterday :slightly_smiling_face:
Sahil Ahuja
Friday, November 11, 2022 at 7:42 PM
(It works well when I set waitForInitialization to true, but unfortunately that breaks the loading state for my app so prefer not to wait)
tore (statsig)
Friday, November 11, 2022 at 7:46 PM
Everybody prefers not to wait, but I would keep in mind the side effects of not waiting. It will render you app immediately, but the values wont be up to date with what youve defined in Statsig. Once the initialization does complete, it will rerender with the new values, which can cause a flicker if the experience changes
Sahil Ahuja
Friday, November 11, 2022 at 7:46 PM
At this point I'm comfortable with that because we don't have gates that affect the homepage
tore (statsig)
Friday, November 11, 2022 at 7:47 PM
Im still trying to reproduce the issue you described
Sahil Ahuja
Friday, November 11, 2022 at 7:48 PM
Will have to re-evaluate later on if we want to add an experiment on homepage -- I'm not sure if it's possible to block loading of a specific part of homepage using waitForInitialization (anyways not a priority to figure out right now)
tore (statsig)
Friday, November 11, 2022 at 7:53 PM
If you used the loading indicator in that specific hook call, you could block loading that single component
tore (statsig)
Friday, November 11, 2022 at 8:08 PM
hmm Im still unable to reproduce the issue, with `waitForInitialization` false, I just get `isLoading: true, value: false` for `useGate` calls in my component hierarchy
tore (statsig)
Friday, November 11, 2022 at 8:09 PM
(side note, we did publish `4.8.0` as a production version with the other fix we discussed, so you dont have to use the beta version any more
Sahil Ahuja
Friday, November 11, 2022 at 8:09 PM
Hmm that's weird -- ok will try upgrading to that version and circle back
tore (statsig)
Friday, November 11, 2022 at 8:11 PM
To simplify things a bit and try to narrow in on the issue, maybe just simplify the user object you are setting on the provider? Like just hard code it to {userID: “test”}
Sahil Ahuja
Friday, November 11, 2022 at 8:13 PM
Nope that didn't do it
Sahil Ahuja
Friday, November 11, 2022 at 8:16 PM
Ok I found it -- seems like the issue is with how I was declaring the StatsigProvider in a separate file
Sahil Ahuja
Friday, November 11, 2022 at 8:16 PM
Not sure why that would affect things :man-shrugging:
Sahil Ahuja
Friday, November 11, 2022 at 8:16 PM
I moved it into App.tsx and works fine
tore (statsig)
Friday, November 11, 2022 at 8:19 PM
Huh, strange
tore (statsig)
Friday, November 11, 2022 at 8:19 PM
I’m not sure I have an explanation for that, but Im glad its working for you!
Sahil Ahuja
Friday, November 11, 2022 at 8:26 PM
Would any part of the internal implementation of the Provider cause this to happen? It's a bit annoying now because I need to access another context from the same file to get the user info :sweat_smile:
tore (statsig)
Friday, November 11, 2022 at 8:29 PM
Not that I can think of. Could it be something weird with naming it the same thing as the exported StatsigProvider from the sdk?
Sahil Ahuja
Friday, November 11, 2022 at 8:56 PM
So the issue is with calling useAuthContext() from within the Statsig provider i'm creating -- the AuthProvider has all the info on the current user, so without it I can properly initialize the userNid / etc.
If I remove the useAuthContext() and instead try grabbing the id directly from async storage, it also gives the same error saying call and wait for initialization to finish. If I remove all this code and just send in 'test' for nid it works fine
```import type { FC, ReactNode } from 'react';
import React, { useEffect, useState, memo } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import env from 'react-native-config';
import DeviceInfo from 'react-native-device-info';
import { StatsigProvider } from 'statsig-react-native';
const MyStatsigProvider: FC<{
children: ReactNode;
}> = ({ children }) => {
// const { userNid, currentUser, initialize } = useAuthContext();
const [userNid, setUserNid] = useState<number | null>(null);
useEffect(() => {
void (async () => {
const _userNid = (await AsyncStorage.getItem('nid')) ?? null;
setUserNid(_userNid != null ? parseInt(_userNid) : null);
})();
}, []);
return (
<StatsigProvider
sdkKey={env.STATSIG_API_KEY}
user={{
userID: userNid ?? undefined,
appVersion: DeviceInfo.getBuildNumber().toString(),
custom: {
// isInternal: currentUser?.isInternal ?? undefined,
// username: currentUser?.username ?? undefined,
},
}}
waitForInitialization={false}
>
{children}
</StatsigProvider>
);
};
export default MyStatsigProvider;```
Sahil Ahuja
Friday, November 11, 2022 at 8:57 PM
Seems the issue has to do with setting any state here
Sahil Ahuja
Friday, November 11, 2022 at 8:57 PM
Without doing that though not sure what you recommend for grabbing the userId
tore (statsig)
Friday, November 11, 2022 at 9:26 PM
Hmm interesting. So when the user object changes, we do have to re-trigger the network request to update the values. Are you able to only render the provider once you’ve fetched those values?
Sahil Ahuja
Friday, November 11, 2022 at 9:31 PM
Ok yes that works now :slightly_smiling_face: Thanks again for helping me get to the bottom of this. If I return early when userNid is null then it works
tore (statsig)
Friday, November 11, 2022 at 9:36 PM
Hmm okay, the SDK still shouldn’t throw in that case so we will look into that, but I think this is a better integration anyway