---
title: React hooks
description: Every React hook in the library, plus the shared lifecycle for app open, interstitial, rewarded, and rewarded interstitial hooks.
---

## All hooks

| Hook                        | Purpose                                                                                  | Guide                                                                                                      |
| --------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `useAppOpenAd`              | Load and show one app open ad.                                                           | [Below](#app-open)                                                                                         |
| `useAppOpenAdManager`       | Google's app open manager: preload, four-hour freshness, cold-start and warm foreground. | [App open ads](/ad-formats/app-open#cold-and-warm-foreground-lifecycle)                                    |
| `useInterstitialAd`         | Load and show one interstitial.                                                          | [Below](#interstitial)                                                                                     |
| `useRewardedAd`             | Load and show one rewarded ad and read its reward.                                       | [Below](#rewarded)                                                                                         |
| `useRewardedInterstitialAd` | Load and show one rewarded interstitial and read its reward.                             | [Below](#rewarded-interstitial)                                                                            |
| `useGAMInterstitialAd`      | Load and show one Google Ad Manager interstitial, with app events.                       | [Google Ad Manager](/ad-formats/ad-manager#gam-interstitial)                                               |
| `useNativeAd`               | Load and own one native ad for `NativeAdView`.                                           | [Native ads](/ad-formats/native#load-ads)                                                                  |
| `useMultiFormatAd`          | One request that returns a native or Google Ad Manager banner winner.                    | [Multi-format recipe](/preload-pools-and-multiformat-recipes#recipe-multi-format-native-or-banner-count-1) |
| `AdPoolProvider`            | Component that creates and destroys preload pools; gate with `enabled`.                  | [Preload pools](/preload-pools-and-multiformat-recipes#consent-before-pools)                               |
| `useAdPool`                 | Read one pool's creation status and availability.                                        | [Display pool recipe](/preload-pools-and-multiformat-recipes#recipe-display-pool-native--banner-depth-1)   |
| `usePooledAd`               | Poll a pool at show time and own the returned ad.                                        | [Fullscreen pool recipe](/preload-pools-and-multiformat-recipes#recipe-fullscreen-interstitial-pool)       |
| `useForeground`             | Run a callback when the app returns from the background (not on cold start).             | [API reference](https://invertase.github.io/react-native-google-mobile-ads/useForeground.html)             |

On Android, `useForeground` also fires when a fullscreen ad closes, so if your callback shows a
fullscreen ad, guard against showing two back-to-back.

The rest of this page covers the four fullscreen hooks for app open, interstitial, rewarded, and
rewarded interstitial ads. Their v17 options form loads automatically by default and exposes one
shared lifecycle model. `useGAMInterstitialAd` uses the same model.

<Warning>
  Resolve consent before initialization and loading. Keep `autoLoad` false until your consent flow
  says ads may be requested; see [Consent & privacy basics](/consent-basics).
</Warning>

## Choose the hook

Each hook takes the same options shape. Use `TestIds` during development and your own ad unit ID
in production.

### App open

```tsx
import { Button } from 'react-native';
import { TestIds, useAppOpenAd } from 'react-native-google-mobile-ads';

export default function AppOpenButton() {
  const { status, show } = useAppOpenAd({
    adUnitId: TestIds.APP_OPEN,
  });

  return <Button title="Show app open ad" disabled={status !== 'loaded'} onPress={() => show()} />;
}
```

Use app open ads only while a launch or foreground loading screen is visible. For complete cold-
and warm-start handling, see [App open ads](/ad-formats/app-open).

### Interstitial

```tsx
import { Button } from 'react-native';
import { TestIds, useInterstitialAd } from 'react-native-google-mobile-ads';

export default function InterstitialButton() {
  const { status, show } = useInterstitialAd({
    adUnitId: TestIds.INTERSTITIAL,
  });

  return <Button title="Show interstitial" disabled={status !== 'loaded'} onPress={() => show()} />;
}
```

### Rewarded

```tsx
import { useEffect } from 'react';
import { Button } from 'react-native';
import { TestIds, useRewardedAd } from 'react-native-google-mobile-ads';

export default function RewardedButton() {
  const { status, show, reward, earnedReward } = useRewardedAd({
    adUnitId: TestIds.REWARDED,
    requestOptions: {
      serverSideVerificationOptions: {
        userId: 'current-user-id',
        customData: 'reward-source=store',
      },
    },
  });

  useEffect(() => {
    if (earnedReward && reward) {
      console.log(`Grant ${reward.amount} ${reward.type}`);
    }
  }, [earnedReward, reward]);

  return <Button title="Show rewarded ad" disabled={status !== 'loaded'} onPress={() => show()} />;
}
```

In a real app, react to `earnedReward` in an effect or state transition after the SDK reports it;
do not grant a reward merely because the ad opened. Configure and verify
[server-side verification](/ad-formats/rewarded#server-side-verification-ssv) for valuable rewards.

### Rewarded interstitial

```tsx
import { useEffect, useRef, useState } from 'react';
import { Button, Text, View } from 'react-native';
import { TestIds, useRewardedInterstitialAd } from 'react-native-google-mobile-ads';

export default function RewardedInterstitialIntro({
  onContinue,
}: {
  onContinue: (earnedReward: boolean) => void;
}) {
  const [introVisible, setIntroVisible] = useState(false);
  const { status, show, earnedReward } = useRewardedInterstitialAd({
    adUnitId: TestIds.REWARDED_INTERSTITIAL,
  });

  // Move on once when the ad is dismissed, passing whether the reward was earned.
  const latest = useRef({ onContinue, earnedReward });
  latest.current = { onContinue, earnedReward };
  useEffect(() => {
    if (status === 'closed') {
      latest.current.onContinue(latest.current.earnedReward);
    }
  }, [status]);

  if (introVisible) {
    return (
      <View>
        <Text>Watch a short ad to earn 50 coins?</Text>
        <Button
          title="Watch ad"
          onPress={() => {
            setIntroVisible(false);
            show();
          }}
        />
        <Button
          title="Skip"
          onPress={() => {
            setIntroVisible(false);
            onContinue(false);
          }}
        />
      </View>
    );
  }

  return (
    <Button
      title="Continue"
      onPress={() => (status === 'loaded' ? setIntroVisible(true) : onContinue(false))}
    />
  );
}
```

Google requires an intro screen with clear reward messaging and an option to skip before a
rewarded interstitial starts; see
[Rewarded interstitial ads](/ad-formats/rewarded-interstitial).

The hook's `show` swallows a rejected show, so `status` stays `'loaded'` and the next Continue press
returns to the intro; Skip is the way on in that case. The sample also assumes the reward event
arrives before the ad closes. For valuable rewards, rely on
[server-side verification](/ad-formats/rewarded#server-side-verification-ssv) rather than the
client-side order.

The rewarded interstitial hook works on Android and iOS. Pool-based warming for this format is
unavailable on both Android backends (classic and Next-Gen); that pool limitation does not apply to this
load-on-demand hook.

<Info>
  `adUnitId` identifies the placement and manages the ad instance. Changing it creates a new
  instance and destroys the previous one. Setting it to `null` retires the placement, destroys the
  previous instance, and resets `status` to `idle`. Use `autoLoad: false` when the placement exists
  but automatic loading should wait; explicit `load()` and `retry()` still work.
</Info>

The optional `requestOptions` field is sent while loading an advert and supports values such as
keywords, content URLs, and `serverSideVerificationOptions` for rewarded formats. See
[content URL targeting](/ad-formats/interstitial#content-url-targeting-brand-safety) and the
[`RequestOptions`](https://github.com/invertase/react-native-google-mobile-ads/blob/main/packages/core/src/types/RequestOptions.ts)
source for the full set.
Setting additional request options helps AdMob choose better tailored ads from the network.

## Wait for consent with `autoLoad`

```tsx
import { useEffect, useState } from 'react';
import { Button } from 'react-native';
import mobileAds, { TestIds, useInterstitialAd } from 'react-native-google-mobile-ads';

export default function ConsentAwareInterstitial({ canRequestAds }: { canRequestAds: boolean }) {
  const [adsReady, setAdsReady] = useState(false);

  useEffect(() => {
    let cancelled = false;

    if (!canRequestAds) {
      setAdsReady(false);
      return () => {
        cancelled = true;
      };
    }

    const initializeAds = async () => {
      await mobileAds().initialize();
      if (!cancelled) {
        setAdsReady(true);
      }
    };

    initializeAds().catch(error => {
      console.error('Google Mobile Ads initialization failed', error);
    });

    return () => {
      cancelled = true;
    };
  }, [canRequestAds]);

  const { status, show } = useInterstitialAd({
    adUnitId: TestIds.INTERSTITIAL,
    autoLoad: adsReady,
  });

  return <Button title="Continue" disabled={status !== 'loaded'} onPress={() => show()} />;
}
```

Here `canRequestAds` must come from the completed consent flow. `adsReady` becomes true only after
consent permits requests **and** `mobileAds().initialize()` resolves, so the hook cannot load
earlier. Changing `autoLoad` to `false` does not cancel a request already in flight.

## Show the ad

The hook returns several states and functions to control ad.

The fullscreen hooks' `show` is press-safe: it absorbs both the synchronous throw (destroyed ad, or
invalid options on a loaded ad) and the promise rejection (not loaded, already showing, platform
decline), so `onPress={() => show()}` needs no `.catch` or `try`. A press while the ad isn't showable is a
silent no-op and changes no hook state; a platform show failure reported by the ad's `ERROR` event
surfaces as `status: 'error'` with `error` set. This does not apply to the ad returned by `usePooledAd`: its `show()` is not press-safe and uses the imperative two-channel contract (`.catch()` the promise; a destroyed ad throws synchronously). See [preload pools](/preload-pools-and-multiformat-recipes#recipe-fullscreen-interstitial-pool).

```jsx
import { useEffect } from 'react';
import { Button, View } from 'react-native';
import { useInterstitialAd, TestIds } from 'react-native-google-mobile-ads';

export default function App({ navigation }) {
  const { status, show } = useInterstitialAd({
    adUnitId: TestIds.INTERSTITIAL,
  });

  useEffect(() => {
    if (status === 'closed') {
      // Action after the ad is closed
      navigation.navigate('NextScreen');
    }
  }, [status, navigation]);

  return (
    <View>
      <Button
        title="Navigate to next screen"
        onPress={() => {
          if (status === 'loaded') {
            show();
          } else {
            // No advert ready to show yet
            navigation.navigate('NextScreen');
          }
        }}
      />
    </View>
  );
}
```

The options form automatically starts loading the advert. When the user presses the button, the code checks for `status === 'loaded'`, then calls `show()` to present the advert.
Otherwise, if the ad is not loaded, the `navigation.navigate` method is called to navigate to the next screen without showing the ad.
After the ad is closed, `status` becomes `'closed'` and the app navigates to the next screen.

Call `retry()` after an error or no-fill, or call `load()` explicitly when `autoLoad` is false.

All four hooks use the same `status` values:

| Status    | Meaning                                                                 |
| :-------- | :---------------------------------------------------------------------- |
| `idle`    | No load has started, or the options-form ad was destroyed.              |
| `loading` | A load is in flight.                                                    |
| `loaded`  | The ad is ready to show.                                                |
| `showing` | The fullscreen ad is visible.                                           |
| `closed`  | The user dismissed a shown ad.                                          |
| `no-fill` | Loading completed without inventory; retry later, without a tight loop. |
| `error`   | Loading or showing failed; inspect the structured error fields below.   |

`error.phase` identifies the `load` or `show` stage. `error.reason` is the machine-readable
classification to use for branching. `error.message` is human-readable diagnostic text and is not
stable for branching.

Return values of the hook are:

| Name         | Type                     | Description                                                                                      |
| :----------- | :----------------------- | :----------------------------------------------------------------------------------------------- |
| status       | UseFullScreenAdStatus    | Current lifecycle state: idle, loading, loaded, showing, closed, no-fill (load-phase), or error. |
| autoLoad     | boolean                  | Resolved automatic-load policy.                                                                  |
| clicked      | boolean                  | Whether the user clicked this ad.                                                                |
| impression   | boolean                  | Whether this ad recorded an impression.                                                          |
| error        | AdError \| null          | Non-null when status is `no-fill` or `error`.                                                    |
| responseInfo | ResponseInfo \| null     | Response metadata for the current load outcome.                                                  |
| revenue      | PaidEvent \| null        | See [Impression-level ad revenue].                                                               |
| reward       | RewardedAdReward \| null | Reward item; rewarded hooks only.                                                                |
| earnedReward | boolean                  | Whether the user earned the reward; rewarded hooks only.                                         |
| load         | Function                 | Explicitly load using the current request options.                                               |
| retry        | Function                 | Retry after `no-fill` or `error`.                                                                |
| show         | Function                 | Show the loaded advert.                                                                          |
| destroy      | Function                 | Destroy the current ad instance.                                                                 |

Fullscreen `'no-fill'` is load-phase inventory emptiness (`no-fill` or `mediation-no-fill`);
show-phase failures stay `'error'`. See the generated
[AdError reference](https://invertase.github.io/react-native-google-mobile-ads/AdError.html).

In the options form, `destroy()` creates a fresh idle ad with the current arguments but does not
load it, even when `autoLoad` is true; later `load()` or `retry()` uses that replacement.
The positional and imperative-ad forms only destroy the current instance.

`responseInfo` and `revenue` together cover load-time auction metadata and paid
telemetry. See [Revenue telemetry and auction diagnostics](/revenue-telemetry-and-auction-diagnostics).

To warm fullscreen inventory and poll at show time (instead of a one-shot hook), see
[Preload pools and multi-format recipes](/preload-pools-and-multiformat-recipes).

Upgrading from v16? See [Migrating to v17](/migrating-to-v17) for structured errors,
`destroy()` ownership, and the positional-hook deprecation.

[Impression-level ad revenue]: /impression-level-ad-revenue
