# React Native

{% hint style="info" %}
The Hackle React Native SDK supports React 16.8 and above, and React Native 0.64.1 and above.

The React Native SDK is built on top of the [Android SDK](/en/development-guide/android.md) and [iOS SDK](/en/development-guide/ios.md). The following OS versions are supported.

* Android API 16 (4.1 Jelly Bean) and above
* iOS 13 and above
  {% endhint %}

{% hint style="info" %}
Starting from Hackle React Native SDK version 3.31.0, the minimum supported iOS version has been raised to iOS 13.

For versions below Hackle React Native SDK 3.31.0, the minimum supported version is iOS 10.
{% endhint %}

## Add Dependency

{% hint style="warning" %}
After installing or updating the SDK, you must rebuild the app for the integration changes to take effect.
{% endhint %}

[![](https://img.shields.io/npm/v/%40hackler%2Freact-native-sdk)](https://www.npmjs.com/package/@hackler/react-native-sdk)

{% tabs %}
{% tab title="npm" %}

```shell
npm install --save @hackler/react-native-sdk
```

{% endtab %}

{% tab title="yarn" %}

```shell
yarn add @hackler/react-native-sdk
```

{% endtab %}
{% endtabs %}

#### iOS

```shell
cd ios
pod install
```

### Adding Dependency with Expo

{% hint style="info" %}
Expo is supported in React Native SDK version 3.17.0 and above.
{% endhint %}

{% hint style="danger" %}
The React Native SDK does not support the `Expo Go` environment. Please use `expo prebuild`.
{% endhint %}

{% tabs %}
{% tab title="npm" %}

```shell
npm install --save @hackler/react-native-sdk
```

{% endtab %}

{% tab title="yarn" %}

```shell
yarn add @hackler/react-native-sdk
```

{% endtab %}
{% endtabs %}

When using Expo, you do not need to run link or pod install.

### Android Configuration

{% hint style="warning" %}
Only enter the code below manually for React Native SDK version 3.25.0 and below.
{% endhint %}

{% hint style="warning" %}
**Starting from SDK version 3.26.0, the following configuration is applied automatically.** Skip this step and proceed to the next.

Refer to the code below and add `registerActivityLifecycleCallbacks`.

If there is no [Application](https://developer.android.com/reference/android/app/Application) class created, create a new one and register it in `AndroidManifest.xml`.
{% endhint %}

Add the following code to your `Application` class under the `onCreate` function.

{% tabs %}
{% tab title="Java" %}

```java
import android.app.Application;
import io.hackle.android.HackleApp;

public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    ...
    HackleApp.registerActivityLifecycleCallbacks(this);
    ...
  }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
import android.app.Application
import io.hackle.android.Hackle
import io.hackle.android.registerActivityLifecycleCallbacks

class MyApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    ...
    Hackle.registerActivityLifecycleCallbacks(this)
    ...
  }
}
```

{% endtab %}
{% endtabs %}

## SDK Initialization

To use the SDK, you must pass the SDK Key to `createInstance()` to create a `HackleReactNativeSDKClient` and pass it to the `HackleProvider` that wraps your React application.

* You can find the SDK Key in [SDK Integration Info](https://dashboard.hackle.io/config/sdk-setting) on the Hackle Dashboard.

At initialization, the SDK fetches necessary data from the Hackle server and stores it. This typically takes only a few milliseconds. Rendering begins immediately after synchronization is complete.

```javascript
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";

// YOUR_APP_SDK_KEY 자리에 SDK 키를 넣습니다.
const hackleClient = createInstance("YOUR_APP_SDK_KEY");

const App = () => {
  return (
    <HackleProvider hackleClient={hackleClient}>
      <YourApp />
    </HackleProvider>
  );
};
```

### Injecting User at Initialization

{% hint style="info" %}
This feature is supported in React Native SDK version 3.31.0 and above.
{% endhint %}

You can initialize the SDK with user information included.

* If no user information is provided, the user information stored in local storage is used.
* If user information is provided, the user information stored in local storage is not used.
* If no user is injected and there is no user information in local storage, a user with the Hackle Device ID as the device id is used.

{% hint style="info" %}
You can freely update user information after SDK initialization using the user information setter functions.
{% endhint %}

{% hint style="warning" %}
The user information injected at initialization and the user information stored in local storage are not merged.

e.g.) If userId: A is stored in storage and you inject deviceId: B at initialization, the user is set to userId: null, deviceId: B.
{% endhint %}

```javascript
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";

const config = {
  debug: true
};

const user = {
  userId: "YOUR_USER_ID"
}

const hackleClient = createInstance("YOUR_APP_SDK_KEY", config, user);

const App = () => {
  return (
    <HackleProvider hackleClient={hackleClient}>
      <YourApp />
    </HackleProvider>
  );
};
```

### SDK Initialization Config

You can initialize the SDK with configuration options.

```javascript
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";

const config = {
  debug: true
};

const hackleClient = createInstance("YOUR_APP_SDK_KEY", config);

const App = () => {
  return (
    <HackleProvider hackleClient={hackleClient}>
      <YourApp />
    </HackleProvider>
  );
};
```

<table data-full-width="false"><thead><tr><th width="224.4684375">Option</th><th width="295.49">Description</th><th width="125.81">Default</th><th width="99.209375">Supported Version</th></tr></thead><tbody><tr><td><code>exposureEventDedupIntervalMillis</code></td><td>Removes duplicate exposure events for the same A/B Test or Feature Flag distribution result triggered by the same user consecutively.<br>Minimum: 1000 (1 second)<br>Maximum: 3600000 (1 hour)</td><td><code>-1</code> (no dedup)</td><td>3.3.1+</td></tr><tr><td><code>debug</code></td><td>Prints logs for all features to the console and sends events immediately.</td><td><code>false</code></td><td>3.4.1+</td></tr><tr><td><code>pollingIntervalMillis</code></td><td>Periodically updates the configuration set in the Dashboard.<br>Minimum: 60000 (60 seconds)</td><td><code>-1</code> (no periodic update)</td><td>3.6.0+</td></tr><tr><td><code>automaticAppLifecycleTracking</code></td><td>Whether to enable automatic app start/end tracking</td><td><code>true</code></td><td>3.30.0+</td></tr><tr><td><code>automaticScreenTracking</code></td><td>Whether to enable automatic screen tracking</td><td><code>true</code></td><td>3.30.0+</td></tr><tr><td><code>sessionPolicy</code></td><td>Configures session persistence and expiration conditions.</td><td><p><code>persistCondition: alwaysNewSession</code>,</p><p><code>timeoutMillis: 1800000</code> (30 min)</p></td><td>3.32.0+</td></tr><tr><td><code>optOutTracking</code></td><td>Whether opt-out is enabled. When enabled, all event sending is stopped.</td><td><code>false</code></td><td>3.32.0+</td></tr><tr><td><code>sessionTimeoutMillis</code> (deprecated)</td><td>Sets the session expiration time. Please use <code>sessionPolicy</code> instead.</td><td><code>1800000</code> (30 min)</td><td>3.11.0+</td></tr></tbody></table>

#### Session Policy Configuration

You can configure session persistence and expiration conditions using the session policy.

```javascript
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";

const config = {
    sessionPolicy: {
        timeoutMillis: 3600000,
        persistCondition: 'nullToUserId'
    }
};

const hackleClient = createInstance("YOUR_APP_SDK_KEY", config);

const App = () => {
  return (
    <HackleProvider hackleClient={hackleClient}>
      <YourApp />
    </HackleProvider>
  );
};
```

### Refreshing Dashboard Configuration

You can explicitly refresh the Dashboard configuration.

{% hint style="warning" %}
This function can only be called once every 60 seconds.
{% endhint %}

```javascript
hackleClient.fetch();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackle.io/en/development-guide/react-native.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
