> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/development-guide/react-native.md).

# React Native

{% hint style="info" %}
Hackle React Native SDK는 React 17.0.1 이상 및 React Native 0.64.1 이상을 지원합니다.

React Native SDK는 [Android SDK](/development-guide/android.md), [iOS SDK](/development-guide/ios.md) 를 기반으로 작동하며 아래 OS를 지원합니다.

* Android API 24 (7.0 NOUGAT) 이상
* iOS 13 이상
  {% endhint %}

<details>

<summary>React Native SDK 버전 별 OS 지원 정보</summary>

<table><thead><tr><th width="244.765625">Hackle React Native SDK 버전</th><th>지원 OS</th></tr></thead><tbody><tr><td>3.31.0 미만</td><td><ul><li>Android API 16 이상</li><li>iOS 10 이상</li></ul></td></tr><tr><td>3.31.0 이상, 3.36.0 미만</td><td><ul><li>Android API 16 이상</li><li>iOS 13 이상</li></ul></td></tr><tr><td>3.36.0 이상, 4.0.0 미만</td><td><ul><li>Android API 21 이상</li><li>iOS 13 이상</li></ul></td></tr><tr><td>4.0.0 이상</td><td><ul><li>Android API 24 이상</li><li>iOS 13 이상</li></ul></td></tr></tbody></table>

</details>

## 의존성 추가

{% hint style="warning" %}
SDK 설치/업데이트 후 앱을 새롭게 빌드해야 연동이 변경사항이 적용됩니다.
{% 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
```

### Expo 사용 시 의존성 추가

{% hint style="info" %}
React Native SDK 3.17.0 이상 버전에서 Expo를 지원합니다.
{% endhint %}

{% hint style="danger" %}
React Native SDK는 `Expo Go` 환경을 지원하지 않습니다. `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 %}

expo 사용 시에는 link나 pod install은 실행하지 않아도 무방합니다.

### 안드로이드 설정

{% hint style="warning" %}
React Native SDK 3.25.0 이하 버전에서만 아래 코드를 직접 입력해주세요.
{% endhint %}

{% hint style="warning" %}
**SDK 3.26.0 이상 버전부터는 아래 설정이 자동으로 적용**됩니다. 이 단계를 건너뛰고 다음으로 진행해 주세요.

아래 코드를 참고해서 `registerActivityLifecycleCallbacks`를 추가해주세요.

생성된 [Application](https://developer.android.com/reference/android/app/Application) 클래스가 없다면 새로 생성하여 `AndroidManifest.xml`에 등록해 주세요.
{% endhint %}

`Application` 클래스에 다음과 같은 코드를 `onCreate` 함수 아래 추가해 주세요.

{% 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 초기화

SDK를 사용하기 위해서 반드시 `createInstance()`에 SDK 키를 전달하여 `HackleReactNativeSDKClient`를 생성하고 React 어플리케이션을 감싸는 `HackleProvider`에 전달해야 합니다.

* SDK 키는 핵클 서비스의 대시보드 안에 위치한 [SDK 연동 정보](https://dashboard.hackle.io/config/sdk-setting)에서 확인하실 수 있습니다.

초기화 시 핵클 서버로부터 필요한 정보들을 가져와 SDK에 저장합니다. 일반적으로 이 시간은 수 밀리 초에 불과합니다. 동기화가 완료되면 즉시 렌더링이 진행됩니다.

{% hint style="warning" %}
**초기화가 완료되기 전에는 SDK 기능을 호출하지 마세요.**

초기화는 비동기로 진행되며, 핵클 서버와의 동기화가 끝나야 완료됩니다. 초기화가 완료되기 전에 SDK 기능을 호출하면 SDK가 정상적으로 동작하지 않거나 이벤트가 유실될 수 있습니다.

* **A/B 테스트, 기능 플래그, 리모트 컨피그가 정상 동작하지 않습니다.** 실제 분배 결과 대신 기본 그룹(`A`), 꺼짐(`false`), 호출 시 전달한 기본값을 리턴합니다. (사유: `SDK_NOT_READY`)
* **노출 이벤트가 기록되지 않습니다.** 사용자가 실제로 실험 대상이었더라도 노출로 집계되지 않아 실험 결과가 왜곡될 수 있습니다.
* **이벤트가 유실될 수 있습니다.** `track()`으로 수집한 이벤트가 전송되지 않을 수 있습니다.
* **이벤트에 세션 ID가 부정확하게 남을 수 있습니다.**
* **인앱 메시지가 노출되지 않습니다.** 발동 조건은 이벤트가 수집되는 시점에 평가되며, 초기화 완료 전에 수집된 이벤트는 초기화 이후 다시 평가되지 않습니다.

SDK 기능 호출은 반드시 초기화 완료 이후에 실행해 주세요.
{% endhint %}

```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>
  );
};
```

### 초기화 시 사용자 주입

{% hint style="info" %}
React Native SDK 3.31.0 버전 이상에서 지원하는 기능입니다.
{% endhint %}

유저 정보를 포함하여 SDK를 초기화 할 수 있습니다.

* 유저 정보를 포함하지 않으면 로컬 스토리지에 저장된 유저 정보를 사용합니다.
* 유저 정보를 포함하는 경우 로컬 스토리지에 저장된 유저 정보는 사용하지 않습니다.
* 사용자 주입을 하지 않고, 로컬 스토리지에 저장된 유저 정보도 없는 경우 Hackle Device ID를 device id로 가지고 유저를 사용합니다.

{% hint style="info" %}
유저 정보는 SDK 초기화 이후에도 유저 정보 설정 함수를 통해 자유롭게 수정 할 수 있습니다.
{% endhint %}

{% hint style="warning" %}
초기화 시 주입한 유저 정보와 로컬 스토리지에 저장된 유저 정보는 병합하지 않습니다.

ex) 스토리지에 userId: A 가 저장된 상태에서 초기화 시 deviceId: B 를 주입하는 경우, 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를 초기화 할 수 있습니다

```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">설정</th><th width="295.49">기능</th><th width="125.81">기본값</th><th width="99.209375">지원 버전</th></tr></thead><tbody><tr><td><code>exposureEventDedupIntervalMillis</code></td><td>동일한 사용자가 연속으로 발생시킨 동일한 A/B 테스트, 기능플래그 분배결과에 대한 노출 이벤트를 제거합니다.<br>최솟값: 1000 (1초)<br>최댓값: 3600000 (1시간)</td><td><code>-1</code> (중복제거 하지 않음)</td><td>3.3.1+</td></tr><tr><td><code>debug</code></td><td>모든 기능에 대한 로그를 콘솔에 출력하고, 이벤트를 즉시 전송합니다.</td><td><code>false</code></td><td>3.4.1+</td></tr><tr><td><code>pollingIntervalMillis</code></td><td>대시보드에서 설정한 정보를 주기적으로 업데이트 할 수 있습니다.<br>최솟값 : 60000 (60초)</td><td><code>-1</code> (주기적으로 업데이트하지 않음)</td><td>3.6.0+</td></tr><tr><td><code>automaticAppLifecycleTracking</code></td><td>앱 시작 / 종료 자동 추적 활성화 여부</td><td><code>true</code></td><td>3.30.0+</td></tr><tr><td><code>automaticScreenTracking</code></td><td>화면 자동 추적 활성화 여부</td><td><code>true</code></td><td>3.30.0+</td></tr><tr><td><code>sessionPolicy</code></td><td>세션 유지 조건과 만료 조건을 설정합니다.</td><td><p><code>persistCondition: alwaysNewSession</code>,</p><p><code>timeoutMillis: 1800000</code> (30분)</p></td><td>3.32.0+</td></tr><tr><td><code>optOutTracking</code></td><td>옵트아웃 활성화 여부. 활성화 시 모든 이벤트 전송이 중단됩니다.</td><td><code>false</code></td><td>3.32.0+</td></tr><tr><td><code>evaluationMode</code></td><td>평가 방식을 설정합니다.</td><td><code>"local"</code></td><td>4.0.0+</td></tr><tr><td><code>manualScreenViewDedupEnabled</code></td><td><code>setCurrentScreen</code>으로 현재 화면과 동일한 화면을 다시 설정할 때 화면 조회 이벤트를 중복 제거할지 여부입니다. <code>false</code>로 설정하면 동일한 화면을 다시 설정할 때마다 <code>$page_view</code>가 발행됩니다.</td><td><code>true</code></td><td>4.1.0+</td></tr><tr><td><code>sessionTimeoutMillis</code> (deprecated)</td><td>세션만료 시간을 설정합니다. <code>sessionPolicy</code>를 사용해 주세요.</td><td><code>1800000</code> (30분)</td><td>3.11.0+</td></tr></tbody></table>

#### 평가 방식 설정

평가를 SDK에서 직접 수행할지, 핵클 서버가 미리 수행한 결과를 조회할지 선택할 수 있습니다.\
설정하지 않으면 기본값인 `"local"`(로컬 평가)로 동작합니다.

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

const config = {
  evaluationMode: "remote"
};

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

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

{% hint style="warning" %}
원격 평가를 사용하면 기기 내부에 사용자 정보를 저장하지 않습니다. 기존에 로컬 평가를 사용하며 저장된 사용자 정보가 있는 경우 삭제 처리합니다.

두 방식의 차이와 선택 기준은 [평가 방식](/development-guide/sdk/evaluation-mode.md) 문서를 참고 바랍니다.
{% endhint %}

#### 세션 정책 설정

세션 정책을 설정하여 세션의 유지 조건과 만료 조건을 제어할 수 있습니다.

```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>
  );
};
```

### 대시보드 설정 정보 갱신

대시보드 설정 정보를 명시적으로 갱신 할 수 있습니다.

{% hint style="warning" %}
해당 함수는 60초에 한번 제한적으로 호출할 수 있습니다.
{% endhint %}

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
