# How do React Native subscription plans work with Saga?

> Published 2026-10-26T00:42:00.004Z on https://youblog.app/p/how-do-react-native-subscription-plans-work-with-saga/
> Source video: https://www.youtube.com/watch?v=JDVYwtXaigI

A React Native subscription plans flow is a small state machine: plan list, card registration, checkout and an expiry check, all connected through Redux Saga and React Navigation. The 2020 Gustavo Dev Doido lesson builds that loop for a Pagar.me checkout and exposes a reusable pattern for handling plan changes and expired cards.

## React Native subscription plans in this lesson: what gets built

React Native subscription plans in this 2020 Gustavo Dev Doido class resolve to four screens: a plan carousel, a card form, a checkout, and a card list that shows whether the plan is active. Redux Saga owns the Pagar.me API calls, and React Navigation passes the chosen plan and card data between screens.

The episode is lesson eight of the Dev doido series, published on 29 June 2020 on the Gustavo Dev Doido channel. It continues a project whose presentation is deliberately comedic, with the host speaking as Serjão Berranteiro, a Brazilian internet persona built around a 2012 TV Goiânia interview. The architecture underneath is ordinary: React Native screens, React Navigation routes, Redux reducers, Redux Saga side effects, Formik forms, and a Pagar.me payment call.

The repository for the series is public on GitHub as [gumiranda/Aula8DevDoido](https://github.com/gumiranda/Aula8DevDoido). The README for that lesson lists the same scope: subscription plan screen, animated card list, payment screen, form adjustments, `useMemo`/`useEffect`/`useState`, backend refactors, and card listing through Redux Saga. Use the repository as the source of truth for imports, not the spoken transcript.

The plan amounts are shown in the video as R$30, R$60 and R$90, each with a list of features that is partly joke copy. The important mechanics are the three-item plan array, the selected index starting on the middle item, and the route parameter that tells the next screen which amount to charge.

A viewer rebuilding this in 2026 must treat every library version in the episode as historical. The 2020 code targets React Native's older tooling generation, React Navigation 4 according to the video description, and a pagarme client that is no longer the current integration path. The flow logic survives; the exact package wiring does not.

## How the subscription flow moves between screens

The subscription flow moves from the plan carousel to either the card form or an existing card checkout, then to a card list that decides whether the user can pay. React Navigation passes a `plan` object and a `check` flag so the checkout screen knows whether it already has a saved card.

The host lays out three flows. A user with no card goes to the address form and then the new-card screen. A user with an expired plan sees the card list with an 'expired' label and can select a saved card. A user with a valid plan sees the card list with the formatted expiry date and a button that changes the plan or adds a new card.

The branching lives in the `CardList` screen. On mount, an effect reads the `goToHome` parameter from the checkout screen, then checks `user.cpf` and `user.phone`; without them the app navigates to the registration screen. With them, the user sees the card list. Selecting a card navigates to checkout with the saved card's number, brand, holder name and the plan amount.

## Redux Saga and the card list state

Redux Saga handles the Pagar.me card listing and payment side effects, while a reducer stores the returned card array and a boolean that says whether the user has any card. The screen reads both values from the store rather than calling the API itself.

The reducer keeps `cards` as an array initialised empty and `hasCard` as false. Success writes the response array and flips `hasCard`; failure returns the empty array. Logging out clears both values so a different user never sees the prior card list.

The saga calls `GET /cards` using the stored token and dispatches success only when the response array is non-empty. An empty 200 response dispatches failure, which is intentional: an empty list should not be presented as a successful card load. The same pattern reappears for subscription renewal and for the initial card listing.

## React Native subscription plans and the checkout screen

The checkout screen takes the card data and plan amount from route parameters, posts a transaction, and guards against repeated taps. It does not use Redux for its own loading state; a local `useState` flag controls the submit button spinner.

The guard is the part viewers miss. A `count` check runs before the transaction call. The first tap passes, increments the counter and dispatches loading and success; later taps return early. The screen then shows a success alert, navigates to the card list with `goToHome` set so the list refreshes, and clears the loading flag.

On failure the screen shows an error alert, resets the loading flag and lets the user retry. The host notes that a determined user could still bypass this in a real fraud scenario; the counter prevents accidental double submission, not deliberate abuse. Server-side idempotency remains the correct control.

## Library deltas to reconcile before rebuilding

Every payment and navigation package named in the 2020 lesson has a current canonical source with its own version and API, so the 2020 wiring is historical. Reconcile each package before copying the code.

React Native itself now ships on a different architecture generation than the 2020 project. Verify the current install and upgrade path in the [React Native documentation](https://reactnative.dev/docs/getting-started) before adopting older tooling.

React Navigation was on the version 4 API in the 2020 code, with `navigation.getParam` and `navigation.navigate` used together throughout the screens. React Navigation's current documentation describes a newer parameter model, so every route and parameter call needs rechecking against [React Navigation](https://reactnavigation.org/).

Pagar.me is the payment provider in the lesson and its name appears in the API calls. The current integration path differs from the direct client call shown in 2020; the [Pagar.me documentation](https://docs.pagar.me/) is the correct source for the current endpoint, authentication and card tokenisation model.

Formik and Yup handle the registration and card forms. The video calls out that Formik's `initialValues` can behave unexpectedly when a user re-enters a form, and the host adds a check that resets the initial values. Formik's [current documentation](https://formik.org/docs/overview) and Yup's [schema validation guide](https://github.com/jquense/yup) describe the current API for that problem.

date-fns formats the expiry date in the card list. The host uses `format` and `isPast` with the `pt-BR` locale. The [date-fns documentation](https://date-fns.org/) is the canonical reference for that API.

## React Native subscription plans compared with the 2020 stack

The comparison below separates what the 2020 episode shows from the current canonical state of each package. Cells describe status and role, not measured performance.

| Component | 2020 episode state | Current canonical source |
| --- | --- | --- |
| React Native | Older tooling generation | [React Native docs](https://reactnative.dev/docs/getting-started) |
| React Navigation | Version 4 API, `getParam` | [React Navigation](https://reactnavigation.org/) |
| Pagar.me | Direct client call | [Pagar.me docs](https://docs.pagar.me/) |
| Formik and Yup | `initialValues` caveat noted | [Formik](https://formik.org/docs/overview), [Yup](https://github.com/jquense/yup) |
| date-fns | `format` and `isPast` with `pt-BR` | [date-fns](https://date-fns.org/) |

Use the table only as a coverage map. The narrative, not any one row, carries the architecture. The key constraint is that the 2020 code's navigation and payment APIs are historical and must be rebuilt against current documentation rather than copied.

## Where the tutorial's logic is genuinely useful

The parts of the lesson that read as engineering, not comedy, are reusable: route-parameter branching, a duplicate-tap guard, an expiry check driven by a single date, and a store that keeps the card list without persisting it to device storage.

The host deliberately keeps the card array in Redux, not AsyncStorage, with the argument that storing card data on the phone wastes memory and that a fresh request is safer. That is a defensible position for a demo. It is not a compliance statement: card data in memory is still sensitive, and any production app must apply the payment provider's tokenisation and its own storage rules.

The registration form change is also instructive. Adding a check that the `cpf` and `phone` values exist before a navigation was originally missing, and the host adds it during the lesson. That is a small example of a rule that is easy to forget when the happy path dominates the demo.

The series is hosted by Gustavo Miranda under the Dev doido banner, and the earlier lessons are linked from the same repository. The repository description names the further scope of the series. For TypeScript-focused material, the host also runs [Crazystack](https://crazystack.com.br), a separate project that covers full-stack TypeScript development.

One practical constraint: the host renames the screens and adds new routes mid-episode. Anyone copying the code should create `styles.js` alongside each screen, as the host does, rather than inlining every style.

## FAQ

- **What is the main idea of the 2020 subscription lesson?** It shows a React Native subscription flow built on React Navigation, Redux Saga and Pagar.me, with four screens and a card list that reacts to the plan expiry date. The chatty delivery hides ordinary application logic.

- **Which package versions are actually used?** The video description names React Navigation 4 and the host downgrades a navigation dependency to version 1.10.3 of a navigation-related package. The repository README is the source for exact dependency versions.

- **Does the app store card data on the device?** The card list is kept in Redux and fetched from the API on demand; the host explicitly says card data is not written to AsyncStorage. That is a demo-level decision, not a compliance guarantee.

- **How does the app prevent double payments?** A local count in the checkout screen blocks repeated submissions after the first tap. The host acknowledges this is not fraud prevention, and any production flow also needs server-side idempotency.

- **What does the card list show for an expired plan?** It shows the formatted expiry date and an 'expired' label, and selecting a card sends the user to checkout with the saved card data. The plan amount is passed through the navigation route parameter.

## A Working Flow Needs the Boring Rules Written Down

The lesson's real value is not the payment button. It is the small rules that keep a subscription loop coherent: the plan amount travels as a route parameter, the card list re-reads the same date, and the checkout counter stops the second tap.

Those rules are the sort of thing a long video explains well on camera but rarely captures on paper. If your own videos walk through this kind of decision, [Skala Blog](https://skalablog.com) turns a YouTube URL into a written article you can edit and publish.

[Source video](https://www.youtube.com/watch?v=JDVYwtXaigI)
