Skip to main content

Hooks

The React Native SDK provides several React hooks for evaluating feature flags.

useFeatureFlag, useFeatureGate, and the context from useToggly re-evaluate when remote flags refresh or when device-local post-filter gates change via notifyLocalGatesChanged(). See Post-filter gates and Advanced → Device-local post-filter gates.

useFeatureFlag​

Check a single feature flag status.

import { useFeatureFlag } from '@ops-ai/react-native-toggly';

function MyComponent() {
const { isEnabled, isLoading, error } = useFeatureFlag('feature-key');

if (isLoading) return <Loading />;
if (error) return <Error message={error.message} />;

return isEnabled ? <NewFeature /> : <OldFeature />;
}

Return Value​

PropertyTypeDescription
isEnabledbooleanWhether the feature is enabled
isLoadingbooleanWhether the SDK is still loading
errorError | nullAny error that occurred

Options​

const { isEnabled } = useFeatureFlag('feature-key', {
defaultValue: false, // Value to use while loading
});

useFeatureGate​

Check multiple feature flags with all or any requirement.

import { useFeatureGate } from '@ops-ai/react-native-toggly';

function MyComponent() {
// All features must be enabled
const { isEnabled: allEnabled } = useFeatureGate(
['feature1', 'feature2'],
{ requirement: 'all' }
);

// At least one feature must be enabled
const { isEnabled: anyEnabled } = useFeatureGate(
['feature1', 'feature2'],
{ requirement: 'any' }
);

// Negate the result (show when features are OFF)
const { isEnabled: noneEnabled } = useFeatureGate(
['feature1', 'feature2'],
{ requirement: 'all', negate: true }
);
}

Options​

OptionTypeDefaultDescription
requirement'all' | 'any''all'Whether all or any features must be enabled
negatebooleanfalseInverts the result
defaultValuebooleanfalseValue while loading

useToggly​

Access the full Toggly service for advanced operations.

import { useToggly } from '@ops-ai/react-native-toggly';

function MyComponent() {
const {
toggly, // TogglyService instance
isReady, // SDK is initialized
isLoading, // Currently loading
error, // Initialization error
isFeatureOn, // Function to check feature
setIdentity, // Set user identity
refresh, // Manually refresh flags
getFeatureValue, // Get raw feature value
} = useToggly();

const handleLogin = async (userId: string) => {
await setIdentity(userId);
};

const handleLogout = async () => {
await setIdentity(null);
};

const handleRefresh = async () => {
await refresh();
};

// Imperative feature check
const isPremium = isFeatureOn('premium-features');
}

Return Value​

PropertyTypeDescription
togglyTogglyServiceThe underlying Toggly service instance
isReadybooleanWhether the SDK is fully initialized
isLoadingbooleanWhether the SDK is currently loading
errorError | nullAny initialization error
isFeatureOn(key: string) => booleanCheck if a feature is enabled
setIdentity(id: string | null) => Promise<void>Set or clear user identity
refresh() => Promise<void>Manually refresh feature flags
getFeatureValue(key: string) => booleanGet raw feature value

Examples​

Conditional Rendering​

function CheckoutButton() {
const { isEnabled: useNewCheckout, isLoading } = useFeatureFlag('new-checkout');

if (isLoading) {
return <ActivityIndicator />;
}

return useNewCheckout ? (
<NewCheckoutButton onPress={handleNewCheckout} />
) : (
<ClassicCheckoutButton onPress={handleClassicCheckout} />
);
}

Combined Feature Gates​

function PremiumContent() {
const { isEnabled: hasPremiumAccess } = useFeatureGate(
['premium-subscription', 'beta-tester'],
{ requirement: 'any' } // User has premium OR is beta tester
);

if (!hasPremiumAccess) {
return <UpgradePrompt />;
}

return <PremiumContentView />;
}

User Login/Logout​

function AuthButtons() {
const { setIdentity, refresh } = useToggly();
const [user, setUser] = useState(null);

const handleLogin = async (credentials) => {
const userData = await loginAPI(credentials);
setUser(userData);

// Set identity for targeted feature rollouts
await setIdentity(userData.id);
};

const handleLogout = async () => {
await logoutAPI();
setUser(null);

// Clear identity
await setIdentity(null);
};

return (
<View>
{user ? (
<Button title="Logout" onPress={handleLogout} />
) : (
<Button title="Login" onPress={() => handleLogin(credentials)} />
)}
</View>
);
}

Manual Refresh​

function SettingsScreen() {
const { refresh } = useToggly();
const [refreshing, setRefreshing] = useState(false);

const handleRefresh = async () => {
setRefreshing(true);
try {
await refresh();
} finally {
setRefreshing(false);
}
};

return (
<ScrollView
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
}
>
{/* Content */}
</ScrollView>
);
}

Entity context​

Pass the entity into useFeatureFlag / useToggly().isFeatureOn per call. Do not put entity attributes on setIdentity. See Entity & page context.

const { enabled } = useFeatureFlag('OrderBadge', { context: order, contextKind: 'Order' })

Clients register mappers locally only. Missing context fails closed.

Best Practices​

  1. Use useFeatureFlag for single flags - It's optimized for single feature checks
  2. Use useFeatureGate for multiple flags - When you need AND/OR logic
  3. Use useToggly for advanced operations - Identity management, manual refresh
  4. Handle loading states - Show appropriate UI while flags are loading
  5. Provide defaults - Use featureDefaults for offline scenarios