---
title: Handling flow collectors in React Native
description: Handle ACTION, FLOW_BUTTON, and FLOW_LINK collectors in a React Native DaVinci flow.
component: orchsdks
page_id: orchsdks:davinci:usage/react-native/collectors/flow
canonical_url: https://developer.pingidentity.com/orchsdks/davinci/usage/react-native/collectors/flow.html
llms_txt: https://developer.pingidentity.com/orchsdks/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: Fri, 28 Aug 2026 00:00:00 +0000
keywords: ["DaVinci", "React Native", "FlowCollector", "ACTION", "FLOW_BUTTON", "FLOW_LINK"]
section_ids:
  submitting_a_flow_collector: Submitting a flow collector
---

# Handling flow collectors in React Native

[icon: circle-check, set=far]PingOne [icon: react, set=fab]React Native

* [Prepare](../01-configuring-the-server.html)

* [Install](../02-installing-the-davinci-module.html)

* [Configure](../03-configuring-the-davinci-module.html)

* [Start](../04-starting-a-davinci-flow.html)

* **Navigate**

* [Manage](../06-handling-sessions.html)

A DaVinci flow can return an action that changes the route through the flow instead of collecting the values currently displayed. For example, a flow might offer a **Forgot password** action or a link to a registration branch.

The React Native bridge exposes these actions as `ACTION`, `FLOW_BUTTON`, and `FLOW_LINK` collectors. They are immediate collectors, so your app should render them as buttons or links rather than as ordinary form fields.

When the user activates one, the SDK submits only that flow action and advances to the next node. The action bypasses other values in the current form.

## Submitting a flow collector

Use `submitFlow(flowKey)` when the action is represented by a separate application control. The `flowKey` must match the collector key in the active `ContinueNode`.

`useDaVinciForm` needs access to the `next` action, either through the options argument or through a surrounding `DaVinciProvider`.

Render a flow action

```typescript
import { useEffect } from 'react';
import { Button, Text, View } from 'react-native';
import { useDaVinci, useDaVinciForm } from '@ping-identity/rn-davinci';

function LoginScreen() {
  const { node, next, start } = useDaVinci(davinciClient);
  const form = useDaVinciForm(node, { next });

  useEffect(() => {
    start().catch(() => {}); // error surfaced via hook state
  }, [start]);

  if (node?.type !== 'ContinueNode') return null;

  const flow = form.fields.find(
    field =>
      field.type === 'ACTION' ||
      field.type === 'FLOW_BUTTON' ||
      field.type === 'FLOW_LINK',
  );

  if (!flow) return null;

  return (
    <View>
      <Button
        title={flow.label || flow.key}
        onPress={() => void form.submitFlow(flow.key)}
      />
      <Text>Choose an action to continue.</Text>
    </View>
  );
}
```

You can also connect a rendered control directly to `form.setValue(flow.key, value)`. For a flow collector, that call immediately invokes `next()` with the selected action. Use `submitFlow()` when you want the intent to be explicit or when the control does not directly represent a collector object.

|   |                                                                                                                                                                                                                      |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Do not include `ACTION`, `FLOW_BUTTON`, or `FLOW_LINK` in a normal form payload with the other fields. The form helper excludes these collectors from ordinary submission and handles them as separate flow actions. |

The next result can be another `ContinueNode`, a `SuccessNode`, an `ErrorNode`, or a `FailureNode`. Handle the result with the same node-state logic described in [Stepping through DaVinci flows](../05-stepping-through-davinci-flows.html).
