Statsig in React Native
Supported Features
Installation
Statsig uses a multi-package strategy, so you will need to install both the Statsig client and the React Native specific bindings.
- NPM
- Yarn
npm install @statsig/react-native-bindings
yarn add @statsig/react-native-bindings
Peer Dependencies
The @statsig/react-native-bindings
package has peer dependencies which may also need to be installed if they are not already in your project.
- NPM
- Yarn
npm install react-native-device-info @react-native-async-storage/async-storage
yarn add react-native-device-info @react-native-async-storage/async-storage
React Native + React Specific Setup
The setup for a ReactNative environment is very similar to a plain React environment.
The only difference is that you need to use the ReactNative specific StatsigProviderRN
.
This automatically switches out the storage layer used by the SDK, utilizing AsyncStorage instead of LocalStorage (which isn't available in RN environments).
import {
StatsigProviderRN,
useFeatureGate,
} from '@statsig/react-native-bindings';
function Content() {
const gate = useFeatureGate('a_gate');
// Reason: Network or NetworkNotModified
return (
<View>
<Text>Value: {gate.value ? "Pass" : "Fail"}</Text>
<Text>Reason: {gate.details.reason}</Text>
</View>
);
}
function App() {
return (
<StatsigProviderRN
sdkKey={YOUR_CLIENT_KEY}
user={{ userID: "a-user" }}
loadingComponent={<Text>Loading...</Text>}>
<Content />
</StatsigProviderRN>
);
}
The Basics
You can get an instance of the StatsigClient to check gates, experiments, dynamic configs, layers, and log events.
import { useStatsigClient } from "@statsig/react-native-bindings";
const { client } = useStatsigClient();
See the methods you can call on the client below.
Checking a Feature Flag/Gate
You can evaluate a gate by getting the client with the useStatsigClient
hook,
and then calling checkGate
const { client } = useStatsigClient();
return (
<div>Gate is {client.checkGate('check_user') ? 'passing' : 'failing'}.</div>
);
Getting a DynamicConfig
You can get a DynamicConfig value by getting the client with the useStatsigClient
hook,
and then calling getConfig
const { client } = useStatsigClient();
const config = client.getConfig('app_properties');
return (
<div>{config.get('title', 'Default Title')}</div>
);
Logging an Event
You can get the client with the useStatsigClient
hook, and then call logEvent
const { client } = useStatsigClient();
return <button onClick={() => client.logEvent("button_click")}>Click Me</button>
Getting an Experiment
You can access the experiment variant and parameters for the user by getting the client with the useStatsigClient
hook,
and then calling getExperiment
.
const { client } = useStatsigClient();
const experiment = client.getExperiment('headline_test');
return (
<div>Headline Parameter: {experiment.get('headline', 'Default')}.</div>
);
Getting a Layer
You can access layers and layer parameters for the user by getting the client with the useStatsigClient
hook,
and then calling getLayer
.
const { client } = useStatsigClient();
const layer = client.getLayer('homepage_layer');
return (
<div>Headline Parameter: {layer.get('hero_text', 'Welcome')}.</div>
);
Advanced
StatsigClient Outside the Component Tree
In some scenarios, you may need to use the StatsigClient
when you are not in the React component tree. Things like background tasks or handling notifications.
For these, you can use the Expo specific StatsigClientRN
.
import { StatsigClientRN } from '@statsig/react-native-bindings';
const myClient = new StatsigClientRN(
YOUR_CLIENT_KEY,
{ userID: "a-user" }
);
await myClient.initializeAsync();
if (myClient.checkGate("my_gate")) {
// do something cool
}
Android networking
We have seen reports that the default networking client on react native for android can error out with:
ERROR [Statsig] A networking error occurred during POST request to https://featureassets.org/v1/initialize
Please let us know if you hit this, but for now the suggested workaround is to append this content-type
for all requests:
const customFetcher = (uri, args) => {
args.headers = {
'Content-Type': 'application/json',
...args.headers,
};
return fetch(uri, args);
};
const myStatsigClient = new StatsigClientRN(
'YOUR_KEY',
{
userID: "YOUR_USER_ID",
},
{
networkConfig: {
networkOverrideFunc: customFetcher,
},
}
);
Synchronous Storage with MMKV
Due to the lack of LocalStorage in ReactNative environments, by default the SDK will prefetch all Statsig cache entries during initialization.
If you are utilizing MMKV in your project, and would prefer to use that instead of the default (AsyncStorage).
You can provide you own StorageProvider
via StatsigOptions
.
Something like:
import { MMKV } from "react-native-mmkv";
import { StorageProvider } from "@statsig/client-core";
import { StatsigProviderRN } from '@statsig/react-native-bindings';
function App() {
const [storageProvider] = useState<StorageProvider>(() => {
const mmkv = new MMKV();
return {
isReady: () => true,
isReadyResolver: () => null,
getProviderName: () => "MMKV",
getAllKeys: () => mmkv.getAllKeys(),
getItem: (key: string) => mmkv.getString(key) ?? null,
setItem: (key: string, value: string) => mmkv.set(key, value),
removeItem: (key: string) => mmkv.delete(key),
};
});
return (
<StatsigProviderExpo
sdkKey={YOUR_CLIENT_KEY}
user={{ userID: "a-user" }}
options={{
storageProvider, // <- Passed into StatsigOptions
}}
>
<Text>...</Text>
</StatsigProviderExpo>
);
}