14.7.18 - useIAP Hook Improvements
This release improves the useIAP hook with stable function references, proper option forwarding, and a new reconnect method for manual connection retry.
Stable restorePurchases Reference (#3172)
Problem
restorePurchases was defined as an inline async function in the return object, creating a new function reference on every render. This caused unnecessary re-renders in components that depended on it and broke useCallback/useMemo memoization chains.
Fix
Extracted restorePurchases into a proper useCallback with a stable reference. It also now calls syncIOS() directly instead of going through restorePurchasesTopLevel(), eliminating a redundant getAvailablePurchases network request.
// Before: new function every render + double network call
restorePurchases: async () => {
await restorePurchasesTopLevel(); // calls getAvailablePurchases internally
await getAvailablePurchasesInternal(); // calls it again
}
// After: stable reference + single network call
const restorePurchases = useCallback(async () => {
if (Platform.OS === 'ios') await syncIOS();
await getAvailablePurchasesInternal(options);
}, [getAvailablePurchasesInternal, invokeOnError]);
Forward PurchaseOptions in Hook Methods (#3173)
Problem
The useIAP hook's getAvailablePurchases and restorePurchases methods didn't accept or forward PurchaseOptions. Users couldn't control iOS-specific options (alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS) or Android options (includeSuspendedAndroid) through the hook API.
Fix
Both methods now accept an optional PurchaseOptions parameter and forward it to the underlying API:
const { getAvailablePurchases, restorePurchases } = useIAP();
// Now you can pass options through the hook
await getAvailablePurchases({
onlyIncludeActiveItemsIOS: false,
includeSuspendedAndroid: true,
});
await restorePurchases({
alsoPublishToEventListenerIOS: true,
});
The Android Nitro calls also now correctly forward includeSuspendedAndroid to the native layer.
New reconnect Method (#3174)
Problem
When the initial store connection fails (e.g., Play Store not ready at mount time on Android, or transient network issues), users had no way to retry through the hook — they had to unmount and remount the component.
Fix
Added a reconnect() method that manually retries the store connection:
const { connected, reconnect } = useIAP({
onError: (error) => {
console.warn('Connection failed:', error);
},
});
// Retry connection after failure
const handleRetry = async () => {
const success = await reconnect();
if (success) {
console.log('Reconnected!');
}
};
Key implementation details:
- Shared helpers —
buildAndroidConfig,registerListeners, andcleanupListenersare extracted as shareduseCallbackhelpers used by bothinitIapWithSubscriptionsandreconnect, ensuring consistent behavior - Safe state transitions —
connectedis only set totrueafter listeners are successfully registered, preventing a "connected but no listeners" state - Unmount guard —
isMountedRefcheck after asyncinitConnectionprevents listener leaks if the component unmounts during reconnection - Full listener parity — All listeners are re-registered including
userChoiceBillingAndroid
Upgrade
yarn add react-native-iap@14.7.18
# or
npm install react-native-iap@14.7.18
No breaking changes. The new reconnect method and PurchaseOptions parameter are additive.
