Lesson Description

The "Step-Based Approach" Lesson is part of the full, State Management at Scale in React & Next.js course featured in this preview video. Here's what you'd learn in this lesson:

David discusses the limitations of using a linear step-based approach for multi-step processes and proposes a more flexible solution using a directed graph representation. By transitioning from an array of steps to a graph-based structure, the logic simplifies, allowing for branching, looping, and optional steps in the flow.

Preview
Close

Transcript from the "Step-Based Approach" Lesson

[00:00:00]
>> Learner 1: I've often used the pattern of steps, like the step pattern, to do something similar where I have step one, step two, step three. And I would say the solution that we ended up using was not nearly as elegant to do those step by step processes, but it made use of, I think material has like a stepper function, right.

[00:00:31]
And so trying to incorporate some of that, I feel like this would have been a better approach versus what we ended up doing.
>> David Khourshid: Yeah, so that's actually a, that's a really good thing to call out. So I'm actually going to make a mini, mini demo or just like some demo code.

[00:00:55]
Wait, we already have something here. But actually this is still a good point. So let's say that we have something that's multi step. In fact, let's add another view here. So let's just do function confirm view. And so this is something where basically you can confirm your selection or something like that.

[00:01:21]
In fact, we could just unclick dispatch select flights and we have to add that real quick. Let's do that over here. So type select flight and then flight ID string and then we're just going to add that to the states too. So we have our flow states. So we have our selected flight stringer null and then we could also go to the confirmed states with the selected flight definitely selected thanks to that.

[00:02:00]
So a lot of times, and I'm not going to fully code this out, but we might do something where, like you said, we might have steps where it's, let's say const steps equals. We might first have search and then loading. If you want to put that in steps sometimes like actually it doesn't really make sense to do that, but it does go to show you why, you know, there's limitations to this approach anyway.

[00:02:28]
And then results and then confirm. So what's cool about this is it represents a very simple flow where it's like, okay, the steps are clear, we have step one, step two and step three. In fact, I'm gonna bring this out here to show you. And so we would have something like.

[00:02:49]
Thanks cursor. We would have something like the current step is whatever the current step ID is. Again, we could use what we've learned and say step index set step index equals useState0 grab that from react and then we could derive the current step from that. So const currenStep = steps index.

[00:03:18]
The problem with this though is you basically only have one possible thing you could do, which is go to the next one. So we could say function next step and Then we set the step index to the index +1. You do have to check like am I going to go beyond that array or something like that.

[00:03:37]
And if you do want to get fancy, you have previous step two where you could set the step index to the previous one. So there's a couple of issues with this approach. First of all it's very linear. It assumes that you're going 1, 2, 3 or if you want to do a doubly linked list you would go 3, 2, 1.

[00:03:58]
So you could sort of go backwards. But there might be some steps where for example incomplete you might not want to go back. So now you have to add special logic where it's like if step index is not equal to three in this case, then return because you don't really want to go back from complete but then that's disconnected from the actual logic.

[00:04:23]
So what I like to do instead is make this just a little bit more explicit. And this comes from my experience working with state machines and multi step forms where steps can branch out, steps can loop back, etc., and that is to make a directed graph. So instead of this steps we could have a step graph by the way, no libraries needed here.

[00:04:49]
You could do this just with normal JavaScript. And so we could say, in fact we could keep it super simple. We could say that we have search and then on next we go loading same thing here, result next confirm confirm next complete and then complete. We don't have anything from there but on the loading we could go to search or we could go from results to see this is another instance of let's say we have this.

[00:05:22]
We wouldn't want to go back to the loading screen. So from here we would go back to search and then we could go back to results from the confirm screen. So now we have this graph representation and then our logic actually in my opinion becomes a lot simpler.

[00:05:43]
So next step we have, instead of this current step we would have a const current step set current step equals useState search and then the next step is going to be whatever the current step is next if it exists and if it doesn't exist, just stay with the current step.

[00:06:11]
So typescript's yelling at me, it's totally fine, this is still correct. And then the previous step we would just go based on what the previous one is. So just to illustrate that this graph isn't exactly, you know, it's not linear. Even something as simple as this, I'm going to take this and ask make a state diagram of this.

[00:06:38]
It's probably Going to use Mermaid. But that's cool. We could visualize Mermaid. It's thinking for a bit or it just does it via. Wow,
>> Learners: [LAUGH] This is cool.
>> Learner 2: Excellent.
>> David Khourshid: Yeah, okay, so you can see it's not entirely linear or pretty, but mostly not linear. So we have this happy path flow here.

[00:07:04]
We also see that we could go back from the results. I'm assuming that it's meant to go back here to search and same thing with confirm which it's supposed to go back here to the results might be a formatting thing. Let's ask it to do it as Mermaid and maybe we'll have a better visualization of it.

[00:07:27]
So what we're going to receive is probably something better. So let's copy this and go to see Mermaid.live. Paste it in here. Okay, this is better. So we have search loading. We could go back from here. Results. Once we receive the results back, this is one instance where we're not going back to loading, we're actually going back to search.

[00:07:57]
And then we have this back and forth loop here. You could go next to confirm and back to results or you could go to complete where there is no back. So this goes to show you that even simple flows are not always linear. An array of steps, I've done that before too, plenty of times.

[00:08:16]
But it just doesn't scale once things get a little bit more complicated.
>> Learner 1: Yeah, absolutely. Yeah, because we ran into situations too where some steps were optional.
>> David Khourshid: Yeah, optional steps. That's a big one.
>> Learner 1: Yes.
>> David Khourshid: Yeah.
>> Learner 1: And so then trying to create something that would essentially from a basic like quick glance looks linear is just totally broken.

[00:08:44]
Once you attempt to put too many, what would you say conditionals in it. Because we did exactly the. If you're on step three and you're clicking to the next one and then all of a sudden you need to exit out. We've had to do conditionals within the stepping.

[00:09:04]
So I appreciate that you took the time to at least show how you can graph it versus having just a standard array of keeping all your steps together.
>> David Khourshid: Yeah, absolutely. And if you want to see a visual, not a visual like this, but like a way of how code transforms from that step based approach to more of a grasp based approach.

[00:09:24]
I kid you not, but go to. This is newly released. Go to Jules.Google. And it's sort of my fault that they did this because I made this. Think about it on Twitter. But they basically have this. Don't know if you could see it that well. It says change user onboarding to use a state machine for steps.

[00:09:42]
So it started with that array based step thing. And so it's refactoring it to use that basic state machine set up that, that I showed you. And so you see we have the previous logic where next step is based on the index in the array and it's showing that a potentially better way to do that, that scales once you have more complex flows is to instead do it just by doing an object lookup.

[00:10:12]
So you could see how it changes it here. And in my opinion the logic becomes a lot simpler once you do it that way. That was a little bit painful and it was only two or three steps. So you could just imagine how like with bigger applications it definitely gets messier when you have bigger flows and more complex flows.

[00:10:36]
And that's exactly what we have when we go to the, when we go to the libraries. So libraries exercise. So let me just pull this up. Library,
>> Learner 1: One last comment on-
>> David Khourshid: Yeah, absolutely.
>> Learner 1: The page before we move on. Also too, I noticed that we're still utilizing the on submit within the booking form and we could swap out to using the action.

[00:11:03]
>> David Khourshid: Exactly, yeah.
>> Learner 1: So that we could even reduce the code down substantially more.
>> David Khourshid: Yeah, to be honest, that exercise encompasses a lot of things. I think there's even something there where you can use derived state instead of, you know, the use effect that's going on there.

[00:11:19]
But yeah, there's a lot of things in that where I'm glad that you're recognizing the pattern so that you could see, hey, I could refactor this, I could simplify this or potentially prevent bugs in this part of the code.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now