Closed puopg closed 4 years ago
That is a good use case! I want to make sure I understand where you are checking if Step-3 is complete, is it somewhere in your Step-4 component, or in an onNext
function you are passing to your Wizard
?
I put together this codesandbox for how I understand the use case currently. If you could fork that sandbox and update any parts I didn't catch that would be a huge help to understand if and where we need to make any changes.
Well so I think the flow would be something like:
So to answer the question, it could be either I guess? The Wizard at the high level could be the one who manages the validation, or the step could as well. The main point is that control of the wizard when tied to the route is now given to the browser (hence the back button). Edge case i know, but just curious how one would handle that situation.
Like I mentioned, it's no issue to redirect back to a step that we can actually be on. But doing so without unmounting a
Ah okay now I see what you're saying. So I think in the specific flow you outlined one option might be to use replace
instead of push
when fixing the flow by switching to Step 3. That way the back button would not navigate the browser to Step 4. This codesandbox shows that behavior.
But for the general use case maybe it would be useful to have onNext
run for browser history changes in addition to next
being called. I think that would allow you to make some decisions before unmounting the current step.
I don't think running onNext
would make sense for browser back though so I need to think about that use case a bit more.
@puopg Did you find a satisfactory solution to your issue? I am facing the same scenario and I am looking at limiting the Step
s I pass into the Steps
HOC via some filtering logic like so:
Consider a 5 stage wizard with steps 'a...e
'. Whenever a step has been completed, its corresponding data is stored in my Redux store which looks like this:
store: {
a : [....],
b: [....],
.....
}
My business logic is:
If the user tries to access Step c without completing a or b, the wizard should reroute to /a
If the user tries to access Step c without completing b, but having completed a, they should be led to /b
@nik-john Yea your logic is basically what I wanted. If you break a wizard flow into steps, in order to be on any step, all steps prior must be complete. Otherwise you fall back to the most completed step possible.
What I have done so far is I created a component called the StepValidator, which basically wraps the Steps so like this:
<StepValidator wizard={wizard} validators={this.getValidators()}>
<Steps>
<Step id="connect" name="connect"}>
<GroupingStep next={next}/>
</Step>
<Step id="confirm" name="confirm">
<ConfirmationStep next={next} />
</Step>
</Steps>
</StepValidator>
Where it receives an array of validator functions that can be invoked and they all return a boolean value. Then based on what the wizard sees as the first step, we identify which was the first validator to fail.
So for a set of 3 steps, A, B, and C
The component abstraction is for render control. In the case where validation fails, we want to return nothing while we clean up and change the wizard to the correct step. Once the correct step is reached, our validation will be passing, and we allow the children to render.
That's a pretty good idea. I came up with a similar one, wherein I created the validators on my selectors file. I'll update the progress here
Nice! I think composition is definitely the way to go for this use case.
Imagine this use case.
We have 10 steps in this wizard, and we should only be able to get to Step N, given Steps 1 -> N have been completed.
If this wizard is tied to the router, the browser has the previous history of where the user has been. Which means, they can get to a step via a route on their browsers history stack by hitting the back button lets say.
So this can be solved by fixing the route or fixing the current step. If we are currently rendering the Step-3 Component, and we try to move to Step-4, but Step-3 is not yet complete, we would essentially just move back to Step-3. So cool this is great!
But what it causes is a remount of the Step-3 component. Is there a better way to handle an edge case like this? Thanks!