Advance React Navigation: Handling Complicated Flows Like a Pro

Sep 18, 2024

Advance React Navigation: Handling Complicated Flows Like a Pro

Learn how Charlotte, React Native Tech Lead at Theodo Apps, simplifies complex app flows using state machines and a custom Flow Navigator for efficient navigation.

Author

Aditi Dixit
Aditi DixitContent Writer

Editor's Note: This blog highlights Charlotte, a React Native Tech Lead at Feodo Apps, as she delves into the intricacies of React Navigation. By integrating state machines and custom navigators, she demonstrates how to streamline complex app flows, making navigation simpler and more efficient for developers.

Hi everyone, I’m Charlotte, a React Native Tech Lead at Feodo apps, and today we’re diving into a topic that impacts all of us—flows. Flows are the backbone of many apps, from onboarding sequences to complex payment funnels. But when these flows grow in complexity, they can become an overwhelming challenge for developers.

When Simplicity Turns Complex

Most apps have flows—a structured sequence of pages where we control the user’s journey. In a perfect world, this structure would remain manageable, but as complexity creeps in, it’s easy for the code to become convoluted. I faced this firsthand when I joined a new project with already implemented flows. My task? Add a simple page to an existing flow.

It sounded easy, right? However, the reality was far from it. The flow’s code had grown into a tangled mess. The challenge wasn’t just adding a page—it was deciphering the logic hidden beneath layers of complexity. As the sole developer tasked with this, I found myself lost in the maze of navigation paths.

A Developer’s Nightmare: Complex Navigation

Fast forward a few months—I had the opportunity to start fresh on a new flow. This time, I was determined to make it right from the start. Today, I want to share how we leveraged the power of state machines to clarify React Navigation and simplify even the most complex flows.

But before we dive into the solution, let’s take a step back and define what we mean by “flows.”

What Exactly is a Flow?

A flow is a predetermined series of pages where the user’s path is predefined, like an onboarding sequence or checkout process. Unlike regular navigation, where users are free to jump from page to page, a flow guides users along a set path, ensuring they click "Next" to reach the subsequent step.

However, things can get messy when logic and conditions start piling up within a flow.

The Hidden Problem of Complex Flows

Consider the flow I had to implement—it looked simple on the surface, but was riddled with conditions and logic. The problem? Using regular page-to-page navigation for such a flow made it almost impossible to get a clear overview of the entire sequence. You had to dive into every page to understand the navigation paths hidden within conditional logic. This made debugging and adding new steps a developer’s nightmare.

So how do we fix this? How can we write code that screams, “These are all the possible pathways!”?

The Ideal Flow Solution: State Machines to the Rescue

Imagine an ideal solution—a system where you can see the entire flow in one place. A system where pages don’t have to “know” which page comes next. Sounds perfect, right?

Well, this is where state machines come in. State machines allow us to define the entire flow—every page and every transition—in one clear place. Let’s break it down with a simple analogy: traffic lights. A traffic light system is a state machine, where each color (red, yellow, green) represents a state, and transitions occur based on predefined events.

In a flow, our states are our pages. Each time the user clicks "Next," we send an event that transitions to the next page. This way, all the logic and pathways are stored in one place—easy to read and understand.

The First Step: Implementing State Machines in React Native

Let’s visualize this. We define a state machine with our flow's steps—pages A, B, C, and D. Each time the user hits "Next," we transition from one state (page) to the next. This is a great start, but there’s a problem—our state is split between the state machine and the navigation.

Whenever we transition states, we also need to update the navigation to display the correct page. If these two states get out of sync, we risk bugs. It’s easy to forget a navigation update, leading to issues that are hard to track down.

The Breakthrough: Merging State and Navigation

This leads us to our next evolution: a more declarative approach. Instead of defining pages inside a traditional navigation stack, we define them based on the state machine’s value. This eliminates the need for manual navigation calls, making the flow much more robust.

But we still encountered issues—most notably, losing out on transition animations. And even worse, we still faced potential bugs due to configuration mistakes.

Building a Custom Navigator: A Game-Changer

And then came the breakthrough: building a custom navigator. One of my colleagues asked, "Why not create a navigator tailored to our specific needs?" And that’s exactly what we did. By building a custom flow navigator, we were able to combine the state machine and navigation into a single, coherent system.

Let me introduce you to the Flow Navigator.

The Flow Navigator: Simplifying Complex Logic

The Flow Navigator looks and behaves like a regular navigator but with one critical difference—you define the flow’s order in one place. Here’s an example: cart review, payment, success. In one glance, you can see the entire flow and its order. And inside each page, like Cart Review, you simply call a method—goToNextStep—to advance to the next page without worrying about its position in the flow.

Internally, this works through an index that tracks which page is currently active. As the user moves through the flow, the index bumps up, ensuring seamless navigation from one step to the next.

Handling Conditional Logic with Ease

Of course, not all flows are linear. What about conditional pages—like a document signing step that only appears once? With the Flow Navigator, we can handle conditional logic effortlessly. For example, we use a Boolean value to determine whether the document signing page appears or not.

Once the condition is met, the page is removed from the flow, and the user moves on. This allows for dynamic, adaptive navigation based on user input or other conditions.

Limitations and Future Possibilities

The Flow Navigator solves many architectural issues, but like any solution, it has limitations. For instance, you can’t always see all the possible pathways at a glance. And while it works well with React Navigation, we haven’t built it for Explore Router yet. However, these are challenges we are actively working on.

Rethinking Flow Architectures

Today, we explored how state machines can transform complex flows into clear, manageable systems. By building custom navigators like the Flow Navigator, we’ve created a tool that makes navigating complex flows easier and more intuitive.

I hope this reflection on flow architecture has inspired you to think about your own app’s navigation in new ways. Next time you face scattered logic, remember the power of state machines and custom navigators—they could be your key to clarity and simplicity.

Subscribe to Our Newsletter

More from the engineering frontline.

Dive deep into our research and insights on design, development, and the impact of various trends to businesses.
Insight
Why Legacy Systems Make Business Growth More Expensive: Navigate A Smarter Path to Legacy Modernization
Sep 23, 2026

Why Legacy Systems Make Business Growth More Expensive: Navigate A Smarter Path to Legacy Modernization

Learn how legacy systems make business growth more expensive and how edge-first modernization can remove constraints without replacing the existing system.

Insight
SSO, Audit Logs and RBAC: The Enterprise Features AI Prototyping Tools Do Not Cover | Sarika Gautam
Sep 23, 2026

SSO, Audit Logs and RBAC: The Enterprise Features AI Prototyping Tools Do Not Cover | Sarika Gautam

Why AI-generated prototypes fail enterprise review: the context behind SSO, the cost of skipping audit logs, and how role explosion makes RBAC a product of its own.

Insight
Feature Flags as Technical Debt: The Cleanup Nobody Schedules
Sep 21, 2026

Feature Flags as Technical Debt: The Cleanup Nobody Schedules

This blog explains how unmanaged feature flags create technical debt and how teams can detect, manage, and remove them safely.

Insight
Building AI-First Enterprises: Why System Design Matters More Than AI Adoption
Sep 21, 2026

Building AI-First Enterprises: Why System Design Matters More Than AI Adoption

This blog explores how system design, architecture, and validation shape AI-first enterprises, while examining AI’s impact on software engineering and human decision-making.

Insight
The Product Studio in the AI Era: What Actually Changes | Sarika Gautam
Sep 21, 2026

The Product Studio in the AI Era: What Actually Changes | Sarika Gautam

What changes in product development when AI writes the code: the shift to architecture, the token cost of unplanned builds, and why juniors still matter.

Insight
AI and the Future of Digital Customer Experience: Where Technology Meets Human Creativity
Sep 18, 2026

AI and the Future of Digital Customer Experience: Where Technology Meets Human Creativity

A discussion on how AI, human creativity, research, and cross-functional collaboration are shaping the future of digital customer experience.

Insight
Scaling Down Before Scaling Up: Why Bigger Servers Don’t Fix Bad Architecture
Sep 17, 2026

Scaling Down Before Scaling Up: Why Bigger Servers Don’t Fix Bad Architecture

This blog explores how inefficient backend architecture can cause performance issues even under low traffic, covering practical ways to reduce database load, API latency, and resource usage before scaling infrastructure.

The Right Conversation Can

Save You Six Months.

Book a call