# React

{% hint style="info" %}
Hackle React SDK는 React 16.8 이상 버전을 지원합니다.

React SDK는 [JavaScript SDK](https://docs.hackle.io/development-guide/javascript) 를 기반으로 동작합니다.
{% endhint %}

## 의존성 추가

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

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

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

{% endtab %}

{% tab title="YARN" %}

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

{% endtab %}
{% endtabs %}

## SDK 초기화

SDK를 사용하기 위해서 반드시 HackleReactSDKClient 를 초기화 해야 합니다.

* `HackleReactSDKClient`는 SDK의 기능을 사용하기 위한 메소드들을 제공하는 클래스입니다.
* SDK 키는 핵클 서비스의 대시보드 안에 위치한 [SDK 연동 정보](https://dashboard.hackle.io/config/sdk-setting) 에서 확인하실 수 있습니다.

어플리케이션 초기화 단계에 핵클 서버와 데이터 동기화를 위한 통신을 진행합니다. 일반적으로 이 시간은 수 밀리 초에 불과합니다. 동기화가 완료되면 즉시 렌더링이 진행됩니다.

{% hint style="warning" %}
Google Tag Manager (GTM) 사용시 주의 사항

GTM을 사용하여 연동을 진행할 경우, Hackle SDK 초기화를 하고, SDK를 GTM 에서 접근할 수 있도록 window에 추가 선언이 필요합니다.
{% endhint %}

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

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

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

ReactDOM.render(
  <HackleProvider hackleClient={hackleClient}>
    <YourApp />
  </HackleProvider>,
  document.getElementById('root')
);

// GTM 연동 시 추가 script
window.hackleClient = hackleClient
```

{% endtab %}

{% tab title="Next.js" %}

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

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

function MyApp({Component, pageProps}) {
  return (
    <HackleProvider hackleClient={hackleClient} supportSSR>
      <Component {...pageProps} />
    </HackleProvider>
  )
}

export default MyApp
```

{% endtab %}

{% tab title="Gatsby" %}

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

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

function App() {
  return (
    <HackleProvider hackleClient={hackleClient} supportSSR>
      <YourApp />
    </HackleProvider>
  )
}

export default App
```

{% endtab %}
{% endtabs %}

### 초기화 설정정보

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

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

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

// 설정정보를 포함하여 초기화
const config = {
  debug: true
};

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

ReactDOM.render(
  <HackleProvider hackleClient={hackleClient}>
    <YourApp />
  </HackleProvider>,
  document.getElementById('root')
);
```

{% endtab %}

{% tab title="Next.js" %}

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

// 설정정보를 포함하여 초기화
const config = {
  debug: true
};

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

function MyApp({Component, pageProps}) {
  return (
    <HackleProvider hackleClient={hackleClient} supportSSR>
      <Component {...pageProps} />
    </HackleProvider>
  )
}

export default MyApp
```

{% endtab %}
{% endtabs %}

#### 모든 설정옵션

<table data-full-width="false"><thead><tr><th width="213.57">설정</th><th width="295.49">기능</th><th width="125.81">기본값</th><th width="108.1">지원 버전</th></tr></thead><tbody><tr><td><code>debug</code></td><td>모든 기능에 대한 로그를 콘솔에 출력합니다.</td><td><code>false</code></td><td>1.0.0+</td></tr><tr><td><code>pollingIntervalMillis</code></td><td>대시보드에서 설정한 정보를 주기적으로 업데이트 할 수 있습니다.<br>최솟값 : 60000 (60초)</td><td><code>-1</code></td><td>11.1.0+</td></tr><tr><td><code>exposureEventDedupIntervalMillis</code></td><td>동일한 사용자가 연속으로 발생시킨 동일한 A/B 테스트, 기능플래그 분배결과에 대한 노출 이벤트를 제거합니다.<br>최솟값: 1000 (1초)<br>최댓값: 3600000 (1시간)</td><td><p><code>60000</code>(1분 / 11.23.0 버전 이상)</p><p><code>-1</code>(중복제거 하지 않음 / 11.23.0 버전 미만)</p></td><td>11.1.0+</td></tr><tr><td><code>sessionTimeoutMillis</code> (deprecated)</td><td>세션만료 시간을 설정합니다. <code>sessionPolicy</code>를 사용해 주세요.</td><td><code>1800000</code> (30분)</td><td>11.8.0+</td></tr><tr><td><code>devTool</code></td><td><a href="react/react-user-explorer">사용자 탐색</a>을 사용할 수 있도록 합니다.</td><td><code>undefined</code></td><td>11.13.0+</td></tr><tr><td><code>autoOpenDevTool</code></td><td>사용자 탐색 버튼이 자동으로 나타나도록 하는 옵션입니다.</td><td><code>false</code></td><td>11.13.0+</td></tr><tr><td><code>user</code></td><td>초기화 시점에 사용자를 주입합니다.</td><td><code>undefined</code></td><td>11.22.3+</td></tr><tr><td><code>sessionPolicy</code></td><td>세션 유지 조건과 만료 조건을 설정합니다.</td><td><p><code>ALWAYS_NEW_SESSION</code> ,</p><p><code>1800000</code></p></td><td>11.54.0+</td></tr><tr><td><code>optOutTracking</code></td><td>옵트아웃 활성화 여부.</td><td><code>false</code></td><td>11.54.0+</td></tr></tbody></table>

#### 세션 정책 설정

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

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

const config = {
    sessionPolicy: {
        timeoutMillis: 3600000,
        persistCondition: HackleSessionPersistConditions.NULL_TO_USER_ID
    }
};

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

ReactDOM.render(
  <HackleProvider hackleClient={hackleClient}>
    <YourApp />
  </HackleProvider>,
  document.getElementById('root')
);
```

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

config에 user를 설정한 경우 유저 정보를 포함하여 SDK를 초기화 할 수 있습니다.

* 유저 정보를 포함하지 않으면 쿠키에 저장된 유저 정보를 사용합니다.
* 유저 정보를 포함하는 경우 쿠키에 저장된 유저 정보는 사용하지 않습니다.
* 쿠키에 저장된 유저 정보가 없는 경우 Hackle Device ID를 device id로 가지고 유저를 사용합니다.

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

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

ex) 쿠키에 `userId: A` 가 저장된 상태에서 초기화 시 `deviceId: B` 를 주입하는 경우, `userId: null, deviceId: B`인 유저로 설정됩니다.
{% endhint %}

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

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

const user = {
  userId: "LOGIN_ID",
  deviceId: "CUSTOM_DEVICE_ID"
};

const config = {
  debug: true,
  user: user
};

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

ReactDOM.render(
  <HackleProvider hackleClient={hackleClient}>
    <YourApp />
  </HackleProvider>,
  document.getElementById('root')
);
```

{% endtab %}

{% tab title="Next.js" %}

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

const user = {
  userId: "LOGIN_ID",
  deviceId: "CUSTOM_DEVICE_ID"
};

const config = {
  debug: true,
  user: user
};

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

function MyApp({Component, pageProps}) {
  return (
    <HackleProvider hackleClient={hackleClient} supportSSR>
      <Component {...pageProps} />
    </HackleProvider>
  )
}

export default MyApp
```

{% endtab %}
{% endtabs %}

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

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

{% hint style="warning" %}
해당 함수는 60초에 한번 제한적으로 호출할 수 있습니다.
{% 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/development-guide/react.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.
