Skip to contentSkip to navigationSkip to topbar
On this page
Looking for more inspiration?Visit the
(information)
You're in the right place! Segment documentation is now part of Twilio Docs. The content you are used to is still here—just in a new home with a refreshed look.

Analytics for React Native Implementation Guide


Once you've installed the Analytics React Native library, you can start collecting data through Segment's tracking methods:

  • Identify
  • Track
  • Screen
  • Group
  • Alias

Identify

identify page anchor

The Identify method lets you tie a user to their actions and record traits about them. This includes a unique user ID and any optional traits you know about them like their email, name, or address. The traits option can include any information you want to tie to the user. When using any of the reserved user traits, be sure the information reflects the name of the trait. For example, email should always be a string of the user's email address.

To send updates for anonymous users who haven't yet signed up for your app, pass null for the userId like in the example below.

Method signatureExample use
identify: (userId: string, userTraits?: JsonMap) => void;

The Track method lets you record the actions your users perform. Every action triggers an event, which also has associated properties that the track method records.

Method signatureExample use
track: (event: string, properties?: JsonMap) => void;

The Screen method lets you record whenever a user sees a screen in your mobile app, along with optional extra information about the page being viewed.

You'll want to record a screen event whenever the user opens a screen in your app. This could be a view, fragment, dialog, or activity depending on your app.

Not all integrations support screen, so when it's not supported explicitly, the screen method tracks as an event with the same parameters.

Method signatureExample use
screen: (name: string, properties?: JsonMap) => void;

For setting up automatic screen tracking, see the Automatic Screen Tracking instructions.


The Group method lets you associate an individual user with a group— whether it's a company, organization, account, project, or team. This includes a unique group identifier and any additional group traits you may know, like company name, industry, or number of employees. You can include any information you want to associate with the group in the traits option. When using any of the reserved group traits, be sure the information reflects the name of the trait. For example, email should always be a string of the user's email address.

Method signatureExample use
group: (groupId: string, groupTraits?: JsonMap) => void;

The Analytics React Native utility methods help you to manage your data. They include:

  • Alias
  • Reset
  • Flush
  • Cleanup

The alias method is used to merge two user identities by connecting two sets of user data as one. This method is required to manage user identities in some of Segment's destinations.

Method signatureExample use
alias: (newUserId: string) => void;

The reset method clears the internal state of the library for the current user and group. This is useful for apps where users can log in and out with different identities over time.

(warning)

Warning

Note: Each time you call reset, a new AnonymousId is generated automatically.

Method signatureExample use
reset: () => void;

By default, the analytics client sends queued events to the API every 30 seconds or when 20 events accumulate, whichever occurs first. This also occurs whenever the app resumes if the user has closed the app with some events unsent. These values can be modified by the flushAt and flushInterval config options. You can also trigger a flush event manually.

Method signatureExample use
flush: () => Promise<void>;

In case you need to reinitialize the client, that is, you've called createClient more than once for the same client in your application lifecycle, use this method on the old client to clear any subscriptions and timers first.

1
let client = createClient({
2
writeKey: 'KEY'
3
});
4
5
client.cleanup();
6
7
client = createClient({
8
writeKey: 'KEY'
9
});

If you don't do this, the old client instance would still exist and retain the timers, making all your events fire twice.

Ideally, you shouldn't have to use this method, and the Segment client should be initialized only once in the application lifecycle.


Analytics React Native was built to be as extensible and customizable as possible to give you the ability to meet your bespoke analytics needs.


Control upload with flush policies

control-upload-with-flush-policies page anchor

To more granularly control when events are uploaded you can use FlushPolicies

A Flush Policy defines the strategy for deciding when to flush, this can be on an interval, on a certain time of day, after receiving a certain number of events or even after receiving a particular event. This gives you even more flexibility on when to send event to Segment.

To make use of flush policies you can set them in the configuration of the client:

1
const client = createClient({
2
// ...
3
flushPolicies: [
4
new CountFlushPolicy(5),
5
new TimerFlushPolicy(500),
6
new StartupFlushPolicy(),
7
],
8
});

One of the main advantages of FlushPolicies is that you can add and remove policies on the fly. This is very powerful when you want to reduce or increase the amount of flushes.

For example you might want to disable flushes if you detect the user has no network:

1
2
import NetInfo from "@react-native-community/netinfo";
3
4
const policiesIfNetworkIsUp = [
5
new CountFlushPolicy(5),
6
new TimerFlushPolicy(500),
7
];
8
9
// Create our client with our policies by default
10
const client = createClient({
11
// ...
12
flushPolicies: policies,
13
});
14
15
// If we detect the user disconnects from the network remove all flush policies,
16
// that way we won't keep attempting to send events to segment but we will still
17
// store them for future upload.
18
// If the network comes back up we add the policies back
19
const unsubscribe = NetInfo.addEventListener((state) => {
20
if (state.isConnected) {
21
client.addFlushPolicy(...policiesIfNetworkIsUp);
22
} else {
23
client.removeFlushPolicy(...policiesIfNetworkIsUp)
24
}
25
});

Create your own flush policies

create-your-own-flush-policies page anchor

You can create a custom FlushPolicy special for your application needs by implementing the FlushPolicy interface. You can also extend the FlushPolicyBase class that already creates and handles the shouldFlush value reset.

A FlushPolicy only needs to implement 2 methods:

  • start(): Executed when the flush policy is enabled and added to the client. This is a good place to start background operations, make async calls, configure things before execution
  • onEvent(event: SegmentEvent): Gets called on every event tracked by your client
  • reset(): Called after a flush is triggered (either by your policy, by another policy or manually)

They also have a shouldFlush observable boolean value. When this is set to true the client will attempt to upload events. Each policy should reset this value to false according to its own logic, although it is pretty common to do it inside the reset method.

1
export class FlushOnScreenEventsPolicy extends FlushPolicyBase {
2
3
onEvent(event: SegmentEvent): void {
4
// Only flush when a screen even happens
5
if (event.type === EventType.ScreenEvent) {
6
this.shouldFlush.value = true;
7
}
8
}
9
10
reset(): void {
11
// Superclass will reset the shouldFlush value so that the next screen event triggers a flush again
12
// But you can also reset the value whenever, say another event comes in or after a timeout
13
super.reset();
14
}
15
}

Automatic screen tracking

automatic-screen-tracking page anchor

As sending a Screen event with each navigation action can get tiresome, it's best to track navigation globally. The implementation is different depending on which library you use for navigation. The two main navigation libraries for React Native are React Navigation(link takes you to an external page) and React Native Navigation(link takes you to an external page).


When setting up React Navigation, you'll essentially find the root level navigation container and call Screen whenever the user navigates to a new screen. Segment's example app(link takes you to an external page) is set up with screen tracking using React Navigation, so you can use it as a guide.

To set up automatic screen tracking with React Navigation:

  1. Find the file where you used the NavigationContainer. This is the main top level container for React Navigation.

  2. In the component, create a new state variable to store the current route name:

    const [routeName, setRouteName] = useState('Unknown');
  3. Create a utility function for determining the name of the selected route outside of the component:

    1
    const getActiveRouteName = (
    2
    state: NavigationState | PartialState<NavigationState> | undefined
    3
    ): string => {
    4
    if (!state || typeof state.index !== 'number') {
    5
    return 'Unknown';
    6
    }
    7
    8
    const route = state.routes[state.index];
    9
    10
    if (route.state) {
    11
    return getActiveRouteName(route.state);
    12
    }
    13
    14
    return route.name;
    15
    };
  4. Pass a function in the onStateChange prop of your NavigationContainer that checks for the active route name and calls client.screen() if the route has changes. You can pass in any additional screen parameters as the second argument for screen calls as needed.

    1
    <NavigationContainer
    2
    onStateChange={(state) => {
    3
    const newRouteName = getActiveRouteName(state);
    4
    5
    if (routeName !== newRouteName) {
    6
    segmentClient.screen(newRouteName);
    7
    setRouteName(newRouteName);
    8
    }
    9
    }}
    10
    >

In order to set up automatic screen tracking while using React Native Navigation(link takes you to an external page):

  1. Use an event listener at the point where you set up the root of your application (for example, Navigation.setRoot).
  2. Access your SegmentClient at the root of your application.
1
// Register the event listener for *registerComponentDidAppearListener*
2
Navigation.events().registerComponentDidAppearListener(({ componentName }) => {
3
segmentClient.screen(componentName);
4
});

You can handle analytics client errors through the errorHandler option.

The error handler configuration receives a function which will get called whenever an error happens on the analytics client. It will receive an argument of SegmentError type.

You can use this error handling to trigger different behaviours in the client when a problem occurs. For example, if the client gets rate limited you could use the error handler to swap flush policies to be less aggressive:

1
const flushPolicies = [new CountFlushPolicy(5), new TimerFlushPolicy(500)];
2
3
const errorHandler = (error: SegmentError) => {
4
if (error.type === ErrorType.NetworkServerLimited) {
5
// Remove all flush policies
6
segmentClient.removeFlushPolicy(...segmentClient.getFlushPolicies());
7
// Add less persistent flush policies
8
segmentClient.addFlushPolicy(
9
new CountFlushPolicy(100),
10
new TimerFlushPolicy(5000)
11
);
12
}
13
};
14
15
const segmentClient = createClient({
16
writeKey: 'WRITE_KEY',
17
trackAppLifecycleEvents: true,
18
collectDeviceId: true,
19
debug: true,
20
trackDeepLinks: true,
21
flushPolicies: flushPolicies,
22
errorHandler: errorHandler,
23
});
24

The reported errors can be of any of the ErrorType enum values.


Report errors from plugins

report-errors-from-plugins page anchor

Plugins can also report errors to the handler by using the .reportInternalError function of the analytics client, Segment recommends that you use the ErrorType.PluginError for consistency, and attaching the innerError with the actual exception that was hit:

1
try {
2
distinctId = await mixpanel.getDistinctId();
3
} catch (e) {
4
analytics.reportInternalError(
5
new SegmentError(ErrorType.PluginError, 'Error: Mixpanel error calling getDistinctId', e)
6
);
7
analytics.logger.warn(e);
8
}

If you need to generate an anonymousId either natively or before the Analytics React Native package is initialized, you can send the anonymousId value from native code. The value has to be generated and stored by the caller. For reference, you can find a working example in the app and reference the code below:

iOS

1
...
2
#import <segment_analytics_react_native-Swift.h>
3
4
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
5
{
6
...
7
// generate your anonymousId value
8
// dispatch it across the bridge
9
10
[AnalyticsReactNative setAnonymousId: @"My-New-Native-Id"];
11
return yes
12
}

Android

1
// MainApplication.java
2
...
3
import com.segmentanalyticsreactnative.AnalyticsReactNativePackage;
4
5
...
6
private AnalyticsReactNativePackage analytics = new AnalyticsReactNativePackage();
7
8
...
9
@Override
10
protected List<ReactPackage> getPackages() {
11
@SuppressWarnings("UnnecessaryLocalVariable")
12
List<ReactPackage> packages = new PackageList(this).getPackages();
13
// AnalyticsReactNative will be autolinked by default, but to send the anonymousId before RN startup you need to manually link it to store a reference to the package
14
packages.add(analytics);
15
return packages;
16
}
17
...
18
@Override
19
public void onCreate() {
20
super.onCreate();
21
...
22
23
// generate your anonymousId value
24
// dispatch it across the bridge
25
26
analytics.setAnonymousId("My-New-Native-Id");
27
}

Retrieving the anonymousId

retrieving-the-anonymousid page anchor

The React Native library does not have a specific method for retrieving the anonymousId. However, you can access this value by calling the following in your code:

segmentClient.userInfo.get().anonymousId

Retrieving the anonymousId can be useful if you need to pass this value to your backend, or if you're using a web view component with Segment's Analytics.js library and need to link user activity.


On Android, Segment's React Native library generates a unique ID by using the DRM API as context.device.id. Some destinations rely on this field being the Android ID, so be sure to double-check the destination's vendor documentation. If you choose to override the default value using a plugin, make sure the identifier you choose complies with Google's User Data Policy. For iOS the context.device.id is set the IDFV.

To collect the Android Advertising ID provided by Play Services, Segment provides a plugin(link takes you to an external page) that can be used to collect that value. This value is set to context.device.advertisingId. For iOS, this plugin(link takes you to an external page) can be used to set the IDFA context.device.advertisingId property.


Using a WebView component with React Native

using-a-webview-component-with-react-native page anchor

If you use a webView component in your app that uses Segment's Analytics.js library, you can use Segment's Querystring API to pass the anonymousId from your React Native app to Analytics.js to ensure activity from anonymous users can be linked across these two sources.

To retrieve and pass the anonymousId:

  1. Retrieve anonymousId from the React Native library using:
const anonymousId = segmentClient.userInfo.get().anonymousId
  1. Pass this value into the querystring that opens the webview using the ajs_aid optional query string parameter noted in the documentation above. For example, the URL that opens your webview might look like:
http://segment.com/?ajs_aid={anonymousId}
  1. When a user clicks the element that opens the webview, Analytics.js will read that parameter and automatically set the anonymousId to whatever value is passed in, linking your events across both libraries to the same user.

View the Analytics React Native changelog on GitHub(link takes you to an external page).