@hackler/react-sdk
v12.1.1
Published
React SDK for Hackle
Readme
Hackle React SDK
Install
npm install @hackler/react-sdk --save
yarn add @hackler/react-sdkUsage
initialize
import { createInstance, HackleProvider } from "@hackler/react-sdk"
const hackleClient = createInstance("YOUR_SDK_KEY")
const user = {
id: "ae2182e0",
properties: {
app_version: "1.0.1",
age: 23,
paying_customer: true
}
}
ReactDOM.render(
<HackleProvider hackleClient={hackleClient} user={user} timeout={1000}>
<YourApp />
</HackleProvider>,
document.getElementById("root")
)The user prop replaces the current user
The user prop is applied only when its value has changed since the last time it was applied (or
hackleClient was replaced) — not on every render, and not merely because the prop is present. When
it is applied, it replaces the current user rather than merging into it. Properties are merged
when both userId and deviceId are unchanged — in local evaluation mode only; in remote evaluation
mode the server resolves properties. If either identifier differs, the previous user is discarded
entirely.
This means the prop and the imperative API overwrite each other. Pick one:
// Imperative — do not pass the `user` prop
const hackleClient = createInstance("YOUR_SDK_KEY")
hackleClient.setUserId("ae2182e0")
// Declarative — do not call setUserId/setDeviceId/resetUser
<HackleProvider hackleClient={hackleClient} user={user}>
<YourApp />
</HackleProvider>Mixing them loses data. If the app passes user={{ deviceId }}, calls setUserId("ae2182e0"), and
then re-renders with a user prop whose value has changed — an added property, say — that
application replaces the user and the user id is gone. The same applies to resetUser(): a logout
call is not undone by a later re-render whose user prop value is unchanged, but it is undone by a
re-render whose value has changed.
A prop that goes absent (null/undefined) and later comes back with the same value it had before
is not applied again, because what is tracked is the last value that was applied, not the current
prop. This is deliberate: it keeps an unrelated toggle from wiping out a setUserId call made while
the prop was absent.
The provider compares the prop by value, so an unstable reference — an inline object literal, say —
costs nothing as long as its property values are primitives or arrays of primitives, which is what
the SDK accepts. A stable reference only matters when a property value is a nested object: those
compare by reference and would otherwise re-apply every render. Pass the prop as a stable reference
in that case — a module-scope constant, or useMemo when it is derived:
const user = useMemo(() => ({ id: userId, properties: { plan } }), [userId, plan])If you only need a starting user and never update it, pass it to createInstance instead and drop
the prop:
const hackleClient = createInstance("YOUR_SDK_KEY", {
user: { id: "ae2182e0", properties: { plan: "premium" } }
})Decide the variation
function App() {
return (
<HackleExperiment experimentKey={42}>
<HackleVariation variation={"A"}>
<OldBlueButton />
</HackleVariation>
<HackleVariation variation={"B"}>
<NewRedButton />
</HackleVariation>
</HackleExperiment>
)
}Records the event
const track = useTrack()
const event = {
key: "purchase",
value: 5000,
properties: {
first_paying: false,
item_count: 5
}
}
<button onClick={() => track(event)}>Purchase</button>