---
title: Decide hooks for the React Native SDK v4+
slug: feature-experimentation/docs/decide-hooks-for-the-react-native-sdk
docTags: 
createdAt: 2026-08-05T20:39:55.000Z
---

Use the decide methods to return feature flag decisions for a user. Each decision includes whether the flag is enabled and which variation the user receives.

## Decide

Returns a decision for a specific feature flag and user.

**Minimum SDK version** – v4.0.0+

For versions 3.x and earlier, see [React Native SDK prior to v4](docId\:Mz5kDck1FPop960mWpkTp).

## useDecide

Returns a flag decision for a single flag key. This is the primary hook for making feature flag decisions in React Native components.

### Parameters

| Parameter           | Type   | Description                                                               |
| ------------------- | ------ | ------------------------------------------------------------------------- |
| `flagKey`           | String | The key of the feature flag.                                              |
| `config` (optional) | Object | Configuration object. See [UseDecideConfig](docId:1QIsG8eFYkYIPmTw6_9aa). |

### Returns

Returns a `UseDecideResult` object — a discriminated union with three possible states:

| State   | `isLoading` | `error` | `decision`           |
| ------- | ----------- | ------- | -------------------- |
| Loading | `true`      | `null`  | `null`               |
| Error   | `false`     | `Error` | `null`               |
| Success | `false`     | `null`  | `OptimizelyDecision` |

### Example

```javascript
import { View } from 'react-native';
import { useDecide, OptimizelyDecideOption } from '@optimizely/react-sdk';

function MyComponent() {
  const { decision, isLoading, error } = useDecide('product_sort', {
    decideOptions: [OptimizelyDecideOption.INCLUDE_REASONS],
  });

  if (isLoading) return <Loading />;
  if (error) return <ErrorDisplay error={error} />;

  const variationKey = decision.variationKey;
  const enabled = decision.enabled;
  const sortMethod = decision.variables['sort_method'];

  return <View>{enabled ? <NewFeature sort={sortMethod} /> : <Default />}</View>;
}
```

### Side effect

Invokes the [decision notification listener](docId:1SxhU55rO2wftlNek4f5U) if this listener is enabled.

## useDecideAsync

Similar to [useDecide](docId:1QIsG8eFYkYIPmTw6_9aa), but uses the underlying async SDK method (`decideAsync`). Use this when your setup involves asynchronous operations such as CMAB (Contextual Multi-Armed Bandit) decisions or async User Profile Service lookups.

### Example

```javascript
import { useDecideAsync } from '@optimizely/react-sdk';

function MyComponent() {
  const { decision, isLoading, error } = useDecideAsync('flag-key');

  if (isLoading) return <Loading />;
  if (error) return <ErrorDisplay error={error} />;
  if (decision.enabled) return <NewFeature />;
  return <Default />;
}
```

## useDecideForKeys

Returns decisions for multiple flag keys in a single call.

### Parameters

| Parameter           | Type   | Description                                                               |
| ------------------- | ------ | ------------------------------------------------------------------------- |
| `flagKeys`          | Array  | Array of string flag keys.                                                |
| `config` (optional) | Object | Configuration object. See [UseDecideConfig](docId:1QIsG8eFYkYIPmTw6_9aa). |

### Returns

Returns a `UseDecideMultiResult` object:

| State   | `isLoading` | `error` | `decisions`                                      |
| ------- | ----------- | ------- | ------------------------------------------------ |
| Loading | `true`      | `null`  | `null`                                           |
| Error   | `false`     | `Error` | `null`                                           |
| Success | `false`     | `null`  | Map of flag keys to `OptimizelyDecision` objects |

### Example

```javascript
import { View } from 'react-native';
import { useDecideForKeys } from '@optimizely/react-sdk';

function MyComponent() {
  const { decisions, isLoading, error } = useDecideForKeys(['flag-a', 'flag-b']);

  if (isLoading) return <Loading />;
  if (error) return <ErrorDisplay error={error} />;

  const flagA = decisions['flag-a'];
  const flagB = decisions['flag-b'];

  return (
    <View>
      {flagA.enabled && <FeatureA />}
      {flagB.enabled && <FeatureB />}
    </View>
  );
}
```

### Side effects

Invokes the [decision notification listener](docId:1SxhU55rO2wftlNek4f5U) if this listener is enabled.

## useDecideForKeysAsync

Similar to [useDecideForKeys](docId:1QIsG8eFYkYIPmTw6_9aa), but uses the underlying async SDK method. Use this for CMAB decisions or async User Profile Service lookups.

```javascript
import { useDecideForKeysAsync } from '@optimizely/react-sdk';

const { decisions, isLoading, error } = useDecideForKeysAsync(['flag-a', 'flag-b']);
```

## useDecideAll

Returns decisions for all active (unarchived) flags in the project.

### Parameters

| Parameter           | Type   | Description                                                               |
| ------------------- | ------ | ------------------------------------------------------------------------- |
| `config` (optional) | Object | Configuration object. See [UseDecideConfig](docId:1QIsG8eFYkYIPmTw6_9aa). |

### Returns

Returns a `UseDecideMultiResult` object (same shape as [useDecideForKeys](docId:1QIsG8eFYkYIPmTw6_9aa)).

### Example

```javascript
import { View, Text } from 'react-native';
import { useDecideAll, OptimizelyDecideOption } from '@optimizely/react-sdk';

function MyComponent() {
  const { decisions, isLoading, error } = useDecideAll({
    decideOptions: [OptimizelyDecideOption.ENABLED_FLAGS_ONLY],
  });

  if (isLoading) return <Loading />;
  if (error) return <ErrorDisplay error={error} />;

  const flagKeys = Object.keys(decisions);
  return (
    <View>
      {flagKeys.map((key) => (
        <View key={key}>
          <Text>{key}: {decisions[key].variationKey}</Text>
        </View>
      ))}
    </View>
  );
}
```

### Side effects

Invokes the [decision notification listener](docId:1SxhU55rO2wftlNek4f5U) if this listener is enabled.

## useDecideAllAsync

Similar to [useDecideAll](docId:1QIsG8eFYkYIPmTw6_9aa), but uses the underlying async SDK method. Use this for CMAB decisions or async User Profile Service lookups.

```javascript
import { useDecideAllAsync } from '@optimizely/react-sdk';

const { decisions, isLoading, error } = useDecideAllAsync();
```

## UseDecideConfig

The optional configuration object accepted by all decide hooks.

| Property                   | Type  | Description                                                           |
| -------------------------- | ----- | --------------------------------------------------------------------- |
| `decideOptions` (optional) | Array | Array of [OptimizelyDecideOption](docId:1QIsG8eFYkYIPmTw6_9aa) enums. |

## `OptimizelyDecideOption`

The following table lists the `OptimizelyDecideOption` enum with an explanation what happens if you set them. In addition to setting these options individually for a decide hook, you can also set them as global defaults when you instantiate the Optimizely client. See [Initialize the React Native SDK](docId\:rOp6O4RHzt41KU8N4cr3P).

| `OptimizelyDecideOption` enum                        | If set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OptimizelyDecideOption.DISABLE_DECISION_EVENT`      | Prevents the SDK from dispatching an [impression](../../end-user-docs/measure-and-analyze-results/what-are-impressions-and-decisions-in-feature-experimentation.mdx) event when serving a variation. This disables decision tracking on the [Optimizely Experiment Results page](../../end-user-docs/measure-and-analyze-results/optimizely-experiment-results-page.mdx). The [decision notification listener](../../developer-docs/configure/notification-listeners/decision-notification-listener.mdx) is still called, with `decisionEventDispatched` set to `false`. |
| `OptimizelyDecideOption.ENABLED_FLAGS_ONLY`          | Returns decisions only for flags that are currently enabled. Used with the decide all method and decide for keys method.<br />When this option is not set, the SDK returns all decisions regardless of whether the flag is enabled.                                                                                                                                                                                                                                                                                                                                      |
| `OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE` | Bypasses the user profile service (both lookup and save) for the decision.<br />When this option is not set, user profile service overrides audience targeting, traffic allocation, and experiment mutual exclusion groups.                                                                                                                                                                                                                                                                                                                                              |
| `OptimizelyDecideOption.INCLUDE_REASONS`             | Adds log messages to the reasons field of the decision. Critical errors are always returned, even if this option is not set.                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `OptimizelyDecideOption.EXCLUDE_VARIABLES`           | Excludes flag variable values from the decision result. Use this option to minimize the returned decision by skipping large JSON variables.                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `OptimizelyDecideOption.IGNORE_CMAB_CACHE`           | Bypasses the CMAB cache and fetches a fresh decision from the CMAB service. Use when you need real-time decisions that reflect the latest context.                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `OptimizelyDecideOption.INVALIDATE_USER_CMAB_CACHE`  | Removes the cached CMAB decision for this user and experiment before making the decision. Use when user context has changed significantly and you want to ensure a fresh decision.                                                                                                                                                                                                                                                                                                                                                                                       |
| `OptimizelyDecideOption.RESET_CMAB_CACHE`            | Clears all entries from the CMAB cache before making the decision. Use sparingly for testing or cache corruption scenarios.                                                                                                                                                                                                                                                                                                                                                                                                                                              |

The following code sample shows how to set options on the `useDecide` hook and as global defaults when you instantiate the Optimizely client:

```javascript
import { View, Text } from 'react-native';
import {
  createInstance,
  createPollingProjectConfigManager,
  createBatchEventProcessor,
  OptimizelyDecideOption,
  OptimizelyProvider,
  useDecide,
} from '@optimizely/react-sdk';

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: 'YOUR_SDK_KEY',
  }),
  eventProcessor: createBatchEventProcessor(),
  defaultDecideOptions: [OptimizelyDecideOption.DISABLE_DECISION_EVENT],
});

function FlagComponent() {
  const { decision, isLoading, error } = useDecide('my_flag', {
    decideOptions: [
      OptimizelyDecideOption.ENABLED_FLAGS_ONLY,
      OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE,
    ],
  });

  if (isLoading) return <Loading />;
  if (error) return <ErrorDisplay error={error} />;

  return <View><Text>{decision.enabled ? 'Enabled' : 'Disabled'}</Text></View>;
}

function App() {
  return (
    <OptimizelyProvider
      client={optimizely}
      user={{ id: 'user123' }}
    >
      <FlagComponent />
    </OptimizelyProvider>
  );
}
```

When modifying skills, adhere to the following best practices:

- **Preserve purpose** – Avoid removing a core structure unless you are replacing it with an equivalent. For example, if the skill uses a table or list format to define platform-specific rules, keep that structure.
- **Be explicit and actionable** – Use clear, imperative language. Tell Mark what to do, not just what to consider.
- **Keep platform logic intact** – Maintain conditional logic if the skill is platform-specific (such as Instagram or LinkedIn). Remove it only if your content use case is limited to a single channel.
- **Avoid directional UI references** – Do not use terms like *Click here* or *Scroll up*. Instead, use context-aware phrasing like *Select a post type*.

## Source files

The language and platform source files containing the implementation for the React Native SDK are available on [GitHub](https://github.com/optimizely/react-sdk).
