React Native hooks

The hooks-first layer of @invitebase/react-native — useInvitebase, useReferralLink, useReferralStatus, useRewards, useCampaignInfo, useTierProgress

React Native is the one platform whose API differs by design: instead of mirroring the core methods one-for-one, @invitebase/react-native wraps them in a hooks-first layer. The imperative client (useInvitebase) exposes the full shared surface for actions; the dedicated hooks below are reactive reads — components re-render automatically when the underlying state changes, backed by the same observer layer as every other platform.

All hooks require your app to be wrapped in InvitebaseProvider — see React Native setup.

useInvitebase

The imperative client — every method of the shared surface, promise-based. Use it for actions; use the dedicated hooks for reactive reads.

const invitebase = useInvitebase();

Returns a stable client object:

MethodSignatureNotes
identify(user: InvitebaseUser) => Promise<void>Reference. Merges anonymous history.
track(event: string, properties?: Record<string, unknown>) => voidReference. Batched, retried, idempotent. Never throws.
getReferralLink(campaignId: string) => Promise<ReferralLink>Reference. Creates on first call.
handleInbound(url: string) => booleanReference. Apply a code from a deep link URL.
resolveReferral() => Promise<ReferralResolution>Reference. Prefer useReferralStatus in components.
applyCode(code: string) => Promise<InboundReferral>Reference. Rejects with invalid_referral_code for bad codes.
getCampaignInfo(campaignId: string) => Promise<CampaignInfo>Prefer useCampaignInfo in components.
getReferrerProgress() => Promise<ReferrerProgress>Prefer useTierProgress in components.
getRewards(filter?: RewardFilter) => Promise<Reward[]>Prefer useRewards in components.
hasReward(kindOrId: string) => Promise<boolean>Render-time availability check.
claimReward(rewardId: string) => Promise<Reward>Exactly-once claim.
reset() => voidCall on logout.

All types are identical to the Web SDK types and generated from the same source.

function SignupScreen() {
  const invitebase = useInvitebase();

  async function onSignedUp(user: { id: string; email: string }) {
    await invitebase.identify({ id: user.id, email: user.email });
    invitebase.track('signup');
  }
  // …
}

The current user's link for a campaign — fetched once, cached, re-bound automatically after identify.

const { link, loading, error } = useReferralLink(campaignId: string);
Return fieldTypeDescription
linkReferralLink | null{ id, url, code, campaignId } once loaded.
loadingbooleanTrue during the initial fetch.
errorInvitebaseError | nullSet if the fetch failed.
import { Share, Button } from 'react-native';
import { useReferralLink } from '@invitebase/react-native';

function InviteButton() {
  const { link, loading } = useReferralLink('7e1f8a3b-4c26-49d0-b591-0d8e2f6a3c15');

  return (
    <Button
      title="Invite a friend"
      disabled={loading}
      onPress={() => link && Share.share({ message: `Get a free month of Mycompany: ${link.url}` })}
    />
  );
}

useReferralStatus

The inbound side: was this user referred, and where does that referral stand? Reactive — re-renders on attribution resolution and on referral state transitions.

const status = useReferralStatus();

Returns:

type ReferralStatus = {
  resolution: 'pending' | 'attributed' | 'needsManualEntry' | 'organic';
  signal?: 'strong' | 'soft';          // when resolution is 'needsManualEntry'
  referral: InboundReferral | null;    // { code, campaignId, referrerName, refereeOffer }
  state: string | null;                // referral lifecycle state, e.g. 'signed_up', 'validated'
};
function WelcomeGate({ children }: { children: React.ReactNode }) {
  const status = useReferralStatus();

  if (status.resolution === 'attributed' && status.referral) {
    return (
      <WelcomeCard
        title={`You were invited by ${status.referral.referrerName ?? 'a friend'}`}
        subtitle={status.referral.refereeOffer ?? ''}
      />
    );
  }
  if (status.resolution === 'needsManualEntry') {
    return <CodeEntrySheet prominence={status.signal ?? 'soft'} />;
  }
  return <>{children}</>;
}

useRewards

The current user's reward ledger, live. Backed by the change-observer layer — the component re-renders the moment a reward is earned, fulfilled, or claimed.

const { rewards, loading, error, refresh } = useRewards(filter?: RewardFilter);
ParameterTypeDescription
filter.statusRewardStatusOptional. pending, available, claimed, fulfilled, expired.
filter.campaignIdstringOptional.
filter.kindstringOptional.
Return fieldTypeDescription
rewardsReward[]Current ledger matching the filter.
loadingbooleanInitial fetch in flight.
errorInvitebaseError | nullLast fetch error, if any.
refresh() => Promise<void>Force a refetch (pull-to-refresh).
function RewardsScreen() {
  const { rewards, refresh } = useRewards({ status: 'available' });
  const invitebase = useInvitebase();

  return (
    <FlatList
      data={rewards}
      onRefresh={refresh}
      refreshing={false}
      keyExtractor={(r) => r.id}
      renderItem={({ item }) => (
        <RewardRow
          title={item.display.title}
          onClaim={async () => {
            await invitebase.claimReward(item.id);
          }}
        />
      )}
    />
  );
}

useCampaignInfo

The public offer for a campaign — display-ready strings for banners and paywall slots. Cached with a short TTL.

const { info, loading, error } = useCampaignInfo(campaignId: string);
Return fieldTypeDescription
infoCampaignInfo | null{ referrerReward, refereeOffer, tiers, qualificationSummary, … }.
loadingbooleanInitial fetch in flight.
errorInvitebaseError | nullLast fetch error, if any.
function ReferralBanner() {
  const { info } = useCampaignInfo('7e1f8a3b-4c26-49d0-b591-0d8e2f6a3c15');
  if (!info) return null;

  return (
    <Banner
      text={`Earn ${info.referrerReward.formatted} per friend`}
      onPress={() => navigation.navigate('Invite')}
    />
  );
}

useTierProgress

The current user's referrer progress — counts, earnings, tier position. Reactive: updates live as referees complete gates.

const { progress, loading, error } = useTierProgress();
Return fieldTypeDescription
progressReferrerProgress | null{ referrals: { pending, validated }, earnings, tier: { current, next, referralsToNext } }.
loadingbooleanInitial fetch in flight.
errorInvitebaseError | nullLast fetch error, if any.
function TierStrip() {
  const { progress } = useTierProgress();
  if (!progress?.tier.next) return null;

  return (
    <Text>
      {progress.tier.referralsToNext} more referrals to unlock {progress.tier.next}
    </Text>
  );
}

What's next

On this page