I would love to implement the following behavior:
User comes to a screen at /list URL that stores its state in search params (e.g. a paginated list -> /list?page=2)
When the user clicks one of the list items, the URL changes to /list/1 and a modal opens. The list itself stays on page no. 2.
A modal itself stores some of its state in search params as well (e.g. /list/1?tab=first).
When the modal is closed, the user returns back to /list?page=2
I started with nested routes on a codesandbox, but I can't wrap my head around this.
What would be a good way to approach this?
Related
If a user goes to a page that requires a context beyond what's on the url, I'd like to redirect them elsewhere. The use case is:
/todos/list - this page shows the user their list of todos. It contains links to:
/todos/edit?id=1 - this page allows the user to view/edit details about a particular todo.
If a user were to go directly to /todos/edit (with no id), I'd like to redirect them to /todos/list. I have tried doing this via navigate('list') conditionally in the constructor. This does update the browser url correctly, but it doesn't render the /todos/list page. Is this possible to do? Or is this not possible to do the para below?
I understand the more common url would be /todos/edit/1 so that reach router would handle my issue w/out me needing to deal with it. However, I'm just using this as an example of a piece of information required to render the page that isn't necessarily part of the the url path.
of course as soon as I type the question in stackoverflow, I find the answer is in the docs right in front of my face:
https://reach.tech/router/api/Redirect
For my application, I have a nav bar which has different functionality for different pages. ie. 1 page has a map and the search will search for addresses and another page has a list and the search bar will filter the list. There are also different buttons on each page too.
What's the best way to implement something like this in react? I've thought about creating a different search bar component for every page and just rendering a different one for each route but I don't have enough experience in React to go ahead with that decision. Is there a more efficient alternative?
Create a new Navbar component named something like NavBarController. While calling the navbar controller component pass in the "Type" as prop. Type should be a state and should change depending on the page the user is on.
<NavBarController type={1}></NavBarController>
You would just create a few different NavBars and then NavBarController will handle whichever navbar you want to display out of your multiple navbars.
Your NavBarController will return something like this:
return (props.type===1?<NavBarHome/>
:props.type===2?<NavBarMap/>
:props.type===3?<NavBarList/>)
I have a panel on the left hand side of my app.
On the right side, the admin can select a 'User Name'. Once the User Name is selected, i need to get categories of the selected user. From the displayed categories, I can chose one for which it will display all the items.
User Name > categories > items
I also want my url to change accordingly like localhost/users/categories/items
The left side will not change at all in this process, hence I do not want to re-render it. At present I have three pages, with the navigation configured.
Actually I want to place some animations on the right side as an option is clicked. The alternative i found was to define onClick and change the component with some animation - but this kind of does not allow me to change the url.
What is the best way to handle this?
I am using next-js in my react application.
The alternative i found was to define onClick and change the component with some animation...
That's a correct approach.
...but this kind of does not allow me to change the url.
You can user browser's history to manipulate url without page reload.
For instance
const state = {};
const pageTitle = 'My Item';
const url = 'users/categories/items';
history.pushState(state, pageTitle, url);
If you have <a href's /> in your page, you might want to override their behaviour too, otherwise they'll trigger a page reload as well.
I was able to prevent navigation as per the v4 docs, but I'm trying to hook up a function so that I can use a modal instead of an alert.
Function:
abandonForm = (route) => {
this.props.showModal('confirm');
console.log('leaving..');
}
In my page:
<NavigationPrompt when={true} message={(location) => this.abandonForm('confirm')} />
this.props.showModal('confirm') activates the modal successfully, but behind the modal the page still transitions - how can I prevent transition until a button in the modal is clicked?
Browsers only allow navigation cancellation by means of the alert box that you've mentioned. This restriction is motivated by phishing/scamming sites that try to use javascript gimmicks to create user experiences that convincingly mimic something that a browser or the OS would do (whom the user trusts). Even the format of the text shown in the alert box is crafted so that it's obvious that it originates from the site.
Of course, as long as the current URL stays within your app, you have control over it using react-router's history. For example you can do the following on navigation:
allow the navigation without confirmation
immediately navigate back to the previous location, but now with a modal on top
navigate away for real this time when the user clicks on a button in the modal.
The disadvantage of this approach (leaving out the sheer complexity of it) is that the user will not get a confirmation dialog if they try to navigate to a different site entirely.
Use:
this.unBlock = this.props.history.block((location, navigateToSelectedRoute) => {
// save navigateToSelectedRoute eg this.navigateToSelectedRoute =
// navigateToSelectedRoute;
// use this.navigateToSelectedRoute() afterwards to navigate to link
// show custom modal using setState
});
and when unblocking is done then call this.unBlock() to remove the listener.
Documentation here for history api
I currently have a button that onClicks to history.goBack but I want it to direct the user to another path if there isn't a previous page (in the case the user visits the page directly by typing in the URL in the URL bar instead of clicking within the site to get there). When I checked out this.props.history there isn't an object containing the history of pages visited or a boolean that tells me if there is a page for history.goBack to work on. How do I check that? Looking at the docs for history library, there is suppose to be an entries property but this somehow didn't make it into react-router.
You can use go() property to move further back.
Eg. go(-1) will be equivalent of goBack() and go(1) will be equivalent of goForward().
I don't think there is a way to list all the paths on the stack, but you could allways implement history that you can push to and control.