Issue
I see the "history stack" referenced a lot when talking about redirection. It was formerly an accessible object in react-router-dom v5, but now is only an implicit thing in v6. What I'm imagining is a series of web pages in a stack, with the page at the top being the one that is currently being rendered.
HEAD {
...page_2 <------ Current page
...page_1
...page_0
} TAIL
Is this a proper visualization of the history stack?
My confusion comes from this article about Navigate which states that the replace prop of navigate "replaces the current entry on the stack instead of pushing a new one."
So what I'm understanding is that, if I wanted to redirect from the current page (page_2) to, say, page_0, and I were to NOT include the replace prop, the following would happen:
HEAD {
...page_0 <------ Current page
...page_2 <------ Past page
...page_1
...page_0
} TAIL
Whereas, if I DID include the replace prop, this would happen:
HEAD {
...page_2 <------ Past page
...page_1
...page_0 <------ Current page
} TAIL
Is this an accurate explanation of what is happening? I have done a few experiments with <Navigate>
with and without the replace prop and I haven't noticed any noticeable effects to functionality. What would happen if I never included the replace prop?
Solution
What does the replace property of <Navigate>
do?
The replace
prop on the Navigate
component is used to render a declarative redirect. In other words, it induces a REPLACE navigation action instead of a PUSH action.
History.replaceState()
The
History.replaceState()
method modifies the current history entry, replacing it with the state object and URL passed in the method parameters. This method is particularly useful when you want to update the state object or URL of the current history entry in response to some user action.
History.pushState()
In an HTML document, the
history.pushState()
method adds an entry to the browser's session history stack.
Your visual representation/mental model of a "history stack" is sufficient.
Additionally, what exactly is the "history stack"?
I have done a few experiments with
<Navigate>
with and without thereplace
prop and I haven't noticed any noticeable effects to functionality. What would happen if I never included the replace prop?
Redirects are commonly used in UI navigation flows where you don't want a user to navigate back to a page they shouldn't access in a way or time you don't want it to be accessed.
Examples:
Authentication Flow example:
UI | Action | History Stack | Path | Back Location | |
---|---|---|---|---|---|
0 | initial | ["/"] |
"/" |
||
1 | Navigate to protected route "/foo" |
PUSH "/foo" | ["/", "/foo"] |
"/foo" |
"/" |
2 | Redirect to authenticate | REPLACE "/login" | ["/", "/login"] |
"/login" |
"/" |
3 | Authentication success, redirect back | REPLACE "/foo" | ["/", "/foo"] |
"/foo" |
"/" |
If we used all PUSH actions the history stack would like ["/", "/foo", "/login", "/foo"]
. After successful authentication if the user issues a back navigation they would navigate back to the login page instead of the home page they were on prior to navigating to the Foo page.
Multi-step Form Flow example:
UI | Action | History Stack | Path | Back Location | |
---|---|---|---|---|---|
0 | initial | ["/"] |
"/" |
||
1 | Navigate to registration flow "/register" |
PUSH "/register/1" | ["/", "/register/1"] |
"/register/1" |
"/" |
2 | Go to step 2 | REPLACE "/register/2" | ["/", "/register/2"] |
"/register/2" |
"/" |
3 | Go to step 3 | REPLACE "/register/3" | ["/", "/register/3"] |
"/register/3" |
"/" |
4 | Oops, made mistake, go back to step 2 | REPLACE "/register/2" | ["/", "/register/2"] |
"/register/2" |
"/" |
5 | Go to step 3 | REPLACE "/register/3" | ["/", "/register/3"] |
"/register/3" |
"/" |
6 | Complete registration, redirect to Welcome Page | REPLACE "/welcome" | ["/", "/welcome"] |
"/welcome" |
"/" |
Note that at any time during this flow if the user clicks the back button they would navigate back to the page they were on prior to starting the flow. This is common in registration flows or cart purchases, where you want to control where and how a user enters and exits the flow.
By controlling the "forward" navigations we control the "back navigation" location. The user can't accidentally navigate back into the middle of a UI flow.
Answered By - Drew Reese
Answer Checked By - - Dawn Plyler (ReactFix Volunteer)