---
title: "Передача данных во флоу в React Native SDK"
description: "Передайте значение из вашего приложения на React Native во флоу и отобразите его в текстовом элементе."
---

> **AI agents**: to search Adapty docs faster and with fewer tokens, install the Adapty skill. Claude Code (self-updating via plugin): `claude plugin marketplace add adaptyteam/adapty-skills && claude plugin install adapty-skills@adapty` — other tools: `npx skills add adaptyteam/adapty-skills --all`

[Кастомный тег](flow-custom-tags) — это переменная с произвольным значением из вашего приложения. После того как вы выберете **Value comes from outside the app** в настройках переменной, приложение сможет задавать её значение через Adapty SDK. Например, текстовый элемент содержит «Coins:» и кастомный тег. Если приложение передаёт «120» для этого тега, пользователи увидят «Coins: 120».

## Прежде чем начать \{#before-you-start\}

Вам необходим Adapty SDK версии 4 или выше. Версии ниже v4 не отображают флоу.

## Добавьте пользовательские теги во флоу \{#add-custom-tags-to-the-flow\}

Чтобы отображать значения из вашего приложения во флоу, настройте кастомные теги в билдере:

1. [Создайте кастомный тег](flow-custom-tags#create-a-custom-tag) для каждого значения, которое передаёт ваше приложение.

   <ZoomImage id="flow-custom-tag-create.webp" width="500px" alt="Форма создания переменной с именем, описанием, типом значения String и начальным значением" />

2. [Вставьте каждый тег в текстовый элемент](flow-custom-tags#add-a-custom-tag-to-a-text-element).
3. Запишите полное имя каждого тега, включая его группу. Именно под этим именем код вашего приложения передаёт каждое значение. Например, если группа `user` содержит тег `streak`, полное имя тега — `user.streak`.

   <ZoomImage id="flow-custom-tag-full-name.webp" width="500px" alt="Вкладка Custom в выпадающем списке Add variable с тегом streak в группе user" />

## Передача значений пользовательских тегов \{#pass-custom-tag-values\}

Передавайте значения вашего приложения в поле `customTags` параметров представления в виде объекта. В компоненте `AdaptyFlowView` параметры передаются через проп `params`. В `createFlowView` — через второй аргумент.

- Каждый ключ — это полное имя пользовательского тега, например `user.streak`.
- Каждое значение — строка, которую видят пользователи вместо тега.
- Каждое значение должно быть понятным для человека: например, «1 250», а не «1250.0». Adapty не форматирует и не переводит его.

`createFlowView` считывает значения один раз при создании представления, поэтому они не изменяются, пока флоу открыт. Если `params` смонтированного `AdaptyFlowView` изменяются, компонент пересоздаёт представление флоу, и флоу начинается заново с первого экрана. Не изменяйте `params`, пока флоу открыт.

<Tabs>
<TabItem value="component" label="React component" default>

```typescript showLineNumbers title="React Native (TSX)"

const flowParams = {
  customTags: {
    'username': 'DragonSlayer42',
    'coins': '1,250',
  },
};

function MyFlow({ flow }: { flow: AdaptyFlow }) {
  return <AdaptyFlowView flow={flow} params={flowParams} style={{ flex: 1 }} />;
}
```

</TabItem>
<TabItem value="modal" label="Модальное отображение">

```typescript showLineNumbers title="React Native"

const customTags = {
  'username': 'DragonSlayer42',
  'coins': '1,250',
};

try {
  const view = await createFlowView(flow, { customTags });
  await view.present();
} catch (error) {
  // handle the error
}
```

</TabItem>
</Tabs>

Чтобы протестировать пользовательские теги, откройте флоу в своём приложении после добавления кода, который устанавливает их значения. Холст конструктора и [предпросмотр на устройствах](paywall-device-compatibility-preview#preview-on-devices) отображают только начальные значения: мобильное приложение Adapty не устанавливает значения пользовательских тегов.

Если ваше приложение уже задаёт значения пользовательских тегов для пейволов на старом Paywall Builder, ознакомьтесь с тем, [чем пользовательские теги во флоу отличаются от старых](migrate-to-flows#custom-tags-from-the-old-paywall-builder).

## Что видят пользователи, если значение отсутствует \{#what-users-see-without-a-value\}

Пользователи видят **Начальное значение** пользовательского тега как резервное в следующих случаях:

- Ваше приложение не передаёт никакого значения для тега.
- Пользователь не обновил приложение до версии, которая передаёт это значение.
- Имя в коде вашего приложения не совпадает с полным именем тега, включая регистр букв.
- Другой пользовательский тег в том же текстовом элементе не имеет значения. В этом случае каждый пользовательский тег в этом текстовом элементе показывает своё начальное значение.

Чтобы ничего не отображалось вместо тега, передайте пустую строку. Adapty считает пустую строку значением, поэтому резервный вариант не показывается.

## Пример: отображение ИМТ на основе ответов онбординга \{#example-show-a-bmi-from-onboarding-answers\}

Флоу может собирать ответы пользователей, а кастомный тег — показывать значение из вашего приложения. Объедините эти возможности, чтобы показывать пользователям результат, который приложение вычисляет на основе их ответов: оценку, рекомендованный план или метрику здоровья:

1. Флоу собирает ответы и передаёт их в ваше приложение.
2. Приложение вычисляет результат.
3. Приложение передаёт результат в следующий флоу в виде значения кастомного тега.

В этом примере онбординг-флоу собирает вес и рост пользователя. Когда пользователь закрывает онбординг-флоу после последнего экрана, приложение вычисляет индекс массы тела (ИМТ). Затем открывается пейвол-флоу, который показывает этот ИМТ.

### Настройте флоу \{#set-up-the-flows\}

1. [Создайте два флоу](paywall-builder-templates): онбординг-флоу, собирающий вес и рост пользователя, и флоу-пейвол, показывающий его ИМТ.
2. Добавьте два поля [**Number**](builder-inputs-and-forms) в онбординг-флоу:
   - Одно для веса в килограммах с **Element ID** `weight`.
   - Одно для роста в сантиметрах с **Element ID** `height`.

   Для обоих полей установите **Format** в значение **Integer**. Поле отправляет значение как текст, точно так, как его ввёл пользователь, а [пример кода](#pass-the-bmi-to-the-paywall) не воспринимает «70.5» и «70,5» одинаково. Целые числа не содержат разделителя дробной части, поэтому код читает их одинаково в любой локали.
3. Чтобы убедиться, что приложение получает оба значения, завершите онбординг-флоу экраном без полей ввода. На этом экране добавьте кнопку с действием [**Close flow**](onboarding-actions#close-flow). Поля отправляют свои значения при потере фокуса или при переходе пользователя на другой экран. Действие Close flow не отправляет их. Пример кода открывает пейвол только в том случае, если пользователь добрался до последнего экрана.
4. В флоу-пейволе [создайте кастомный тег](flow-custom-tags#create-a-custom-tag) с именем `bmi`. В поле **Initial value** введите тире (`—`). Пользователь увидит тире, если приложение не передало значение ИМТ.
5. Добавьте текстовый элемент со словами «Your BMI:» в флоу-пейвол. После этих слов [вставьте кастомный тег `bmi`](flow-custom-tags#add-a-custom-tag-to-a-text-element).
6. Добавьте онбординг-флоу в [плейсмент](placements), например `onboarding`. Добавьте флоу-пейвол в плейсмент с ID `bmi_paywall`. Код из раздела [Pass the BMI to the paywall](#pass-the-bmi-to-the-paywall) получает пейвол по этому ID.

### Передайте ИМТ на пейвол

Соберите вес и рост из событий `flow_user_input` онбординг-флоу, как описано в разделе [Обработка данных из флоу](react-native-flow-input). Чтобы определить, что пользователь дошёл до последнего экрана, отслеживайте событие `flow_screen_showed` с `is_last_screen` равным `true`, как описано в разделе [Отслеживание просмотров экранов флоу](react-native-flow-screen-views). Когда пользователь закроет онбординг-флоу после этого экрана, рассчитайте ИМТ. Затем создайте представление пейвола и передайте ИМТ в кастомный тег `bmi`.

Зарегистрируйте следующие обработчики на `onboardingView` — объекте, который возвращает `createFlowView` для флоу онбординга. У компонента `AdaptyFlowView` нет обработчика `onDisappeared`, поэтому этот пример с ним не работает.

```javascript showLineNumbers title="React Native"

const bodyAnswers = {};
let reachedLastScreen = false;

const unsubscribe = onboardingView.setEventHandlers({
  onAnalytics(name, params) {
    if (name === 'flow_screen_showed' && params.is_last_screen) {
      reachedLastScreen = true;
    }
    if (name === 'flow_user_input' && typeof params.value === 'string') {
      bodyAnswers[params.element_id] = params.value;
    }
    return false; // keep the flow open
  },
  onDisappeared() {
    // Number inputs send their values as strings.
    const weight = Number(bodyAnswers.weight);
    const height = Number(bodyAnswers.height);
    const finished = reachedLastScreen;
    delete bodyAnswers.weight;
    delete bodyAnswers.height;
    reachedLastScreen = false;

    if (finished && weight > 0 && height > 0) {
      const heightInMeters = height / 100;
      const bmi = weight / (heightInMeters * heightInMeters);
      showBmiPaywall(bmi.toLocaleString(undefined, { maximumFractionDigits: 1 }));
    }
    return false;
  },
});

async function showBmiPaywall(bmi) {
  try {
    const flow = await adapty.getFlow('bmi_paywall');
    const view = await createFlowView(flow, { customTags: { 'bmi': bmi } });
    await view.present();
  } catch (error) {
    // handle the error
  }
}
```

`toLocaleString` использует десятичный разделитель из локали пользователя: «22.7» в английской и «22,7» в немецкой.

### Сохраните ИМТ в профиле пользователя \{#save-the-bmi-to-the-users-profile\}

Чтобы показывать пользователям разные флоу на основе их ИМТ, сохраните его как [пользовательский атрибут](react-native-setting-user-attributes#custom-user-attributes) профиля. В дашборде Adapty [создайте пользовательский атрибут типа **Number**](segments#custom-attributes) с ключом `bmi`. Затем показывайте каждый флоу [аудитории](audience), сформированной на основе этого атрибута.

Вызовите метод `updateProfile` в `onDisappeared`, сразу после строки, которая вычисляет `bmi`. Передайте само число, а не отформатированную строку — это нужно, чтобы сегмент мог сравнивать BMI с пороговым значением. Поскольку `onDisappeared` не может быть `async`, обработайте результат через `.catch` вместо `await`:

```javascript showLineNumbers title="React Native"
adapty
  .updateProfile({ codableCustomAttributes: { bmi } })
  .catch((error) => {
    // handle the error
  });
```