How can I dynamically create a Route in React? - reactjs

I'm having trouble finding information on this subject because I don't know exactly what to search for and could use some direction on where I could find more information.
Let's say I have a /blog page where I'm able to create a blog. I click a button that opens a form and I fill out all the information: title of blog, blog message, today's date, etc. After that I submit the post (let's call it First Blog) and I get redirected back to the same /blog page. Now I'm able to click the title of my First Blog post and it redirects me to a new page. Example: /blog/id=0001.
I'm obviously not going to have to manually create a brand new Component each time I make a new post so React must have some way to dynamically create pages and automatically display stored information but I'm having trouble finding sources on how I can implement those features and more importantly what would be the best way to display that information in a new page? I'm assuming I would need to store everything in an array and make it display things based on an id.

Yup you could use useParams for that, https://reactrouter.com/en/main/hooks/use-params
import { Routes, Route, useParams } from 'react-router-dom';
function ProfilePage() {
// Get the userId param from the URL.
let { userId } = useParams();
// ...
}
function App() {
return (
<Routes>
<Route path="users">
<Route path=":userId" element={<ProfilePage />} />
<Route path="me" element={...} />
</Route>
</Routes>
);
}
with :userId, you could think of it as a wild card. For example, if you redirect the user to /users/123, you ccan get useParams() to get the userId and get 123 as a result, which you could use it to fetch to DB or something else.
This method is called route parameters.

Related

How can I construct a link to a "neighbour" resource in react router v6?

I've got a React app using React Router v6. I've got a route matching a path with multiple path parameters, something like this:
/event/:eventId/resource/:resourceId
These are represented by nested routes, something like:
<Route path="/event/:eventId/*" element={<Event />}>
<Route path="resource/:resourceId" element={<Resource />} />
</Route>
I have multiple events and multiple resources. A single resource might appear in the context of multiple events, corresponding to urls like this:
/event/event-1/resource/resource-1
/event/event-2/resource/resource-1
Individual resources are linked to other resources. I want to be able make links on a resource page to the other linked resources, in the context of the same event.
So on the page:
/event/event-1/resource/resource-1,
which renders my Resource component, and given that resource-1 has links to resource-2 and resource-3, I might want to make links to these urls:
/event/event-1/resource/resource-2
/event/event-1/resource/resource-3
But, I don't want to hard-code the paths for those links in my Resource component if I can avoid it.
React Router 6 allows me to create nested routes and links, so I can build up long links without having to know the full path up to that point. Does it provide a nice way to make these links without hard coding the full path?
You can take advantage of generatePath, and/or write your own function helpers:
import { generatePath } from 'react-router-dom';
export function getResourcePath({ eventId, resourceId }) {
return generatePath('/event/:eventId/resource/:resourceId', { eventId, resourceId });
}
In your components:
import { getResourcePath } from '...';
...
<Link to={getResourcePath(...)}/>

How do I make a url contain multiple sections? React

So full disclosure, I'm not sure how to ask this question properly, but I do have a decent example. I'm making a React app and I'm trying to make the url more "descriptive" I suppose.
So it starts off at Home, then I go to a Products page and the url changes from /home to /products. This part is fine.
When I want to go to a specific product from the product page, I want the url to change to /products/example instead of just /example. Do I have to specify this with the Links or is there some cleaner way to get it done?
Right now my only answer is to make the link go to /product/example and have the App.js route to the same url. I'm not sure how to properly ask this question for a Google search so I had to ask it here. If you have an idea how to specifically phrase what I'm asking, I'd appreciate that too.
Thanks in advance.
I believe the example in your URL /products/example is the product name for your product. If so, this can be done in putting the product name as an URL parameter using react-router or react-router-dom if you still have not.
by declaring the route as
import { Switch, Route } from "react-router-dom";
const Router = () => (
<Switch>
<Route exact path="/home" component={()=>return <h1>Home</h1>} />
<Route exact path="/products" component={()=>return <h1>Products</h1>} />
<Route path="/products/:productName" component={props=>return <h1>props.match.params.productName</h1>} />
</Switch>
);
export default Router;
more on that here

how to use react-router for dynamic url

I am building extremely stretchable react app and I am using SSR fro SEO.
but I don't know how to handle URL
Like: user can directly land on this URL, domian.com/delhi/cardiologist
In the backend, I have a system of identifying the components for URL, which is for this case is "Speciality" component in "Location: component
I can't go like this
<Rout path={"delhi"}>
<Location/>
</Route>
cause for this case it's Delhi. but for another user, it will be a different city name, I want to reflect the different city in URL but to render same component due best SEO.
SEO is heart of my app.
I am literally new to this kind of things.
please guide me.
I would recommend adding some structure to the path that makes it easier for you to find the location, say:
<Route path='/search/:city/:specialty' component={Specialty} />
So this would match domian.com/search/delhi/cardiologist. You can customize it to whatever makes sense, it could even be a short letter like just /go/ if you are concerned about URL length because of SEO.
Then, inside the Specialty component, you can use match.params.city and match.params.specialty to get the parameters that you are looking for:
function Specialty({ match }) {
const { city, specialty } = match.params;
return (
<p>Search for {specialty} in the city of {city}</p>
);
}
You could still implement a catch-all route using the path that you want:
<Route path='/:city/:specialty' component={Specialty} />
However, that would require always setting the route at the end, so that it only lands on your <Specialty /> component if it doesn't match any other path that you have.

Show/Hide route components in react

I am working on a React application which has routes like so:
<Switch>
<Route path="/edituser/:username" component={EditUser}/>
<Route path="/createuser/:type" component={EditUser}/>
<Route path="/listusers" component={ListUsers}/>
</Switch>
ListUsers component shows a table with pagination where each component in the table has a link which points to /edituser/:username.
I can edit users by clicking on the item in the table but as expected with react, once I go back to listusers/ the component is loaded again and I will be on the first page of users. I want to be on the page from where I accessed the user in the first place.
What is the best pattern to achieve this? I thought about passing in the page number to /edituser and then back to /listuser but then again I have to load all the paginated results again. Is local storage the only option? Any pointers are much appreciated.
There are two solutions for your problem:
1) Pass last active page ad route parameter and set your pagination accordingly.
<Switch>
<Route path="/edituser/:username" component={EditUser}/>
<Route path="/createuser/:type" component={EditUser}/>
<Route path="/listusers/:pageNumber" component={ListUsers}/>
</Switch>
on your componentDidMount you can use it to set state. For example :
const pageNumber = this.props.match.params.pageNumber;
2) Pass state prop in your routing. For example :
<Link
to={{
pathname: '/listusers',
state: { pageNumber: 1 }
}}/>
on your componentDidMount you can use it to set state. For example :
const pageNumber = this.props.location.state.pageNumber;
You could add the page number to the URL in the /listusers endpoint. Maybe something like /listusers/2 or /listusers?page=2 this way, when you hit the browser's back button, you're directly there. One last thing you could do but I wouldn't advise in this case is to store the page number in the history state.
As a rule of thumb, in order to get back, prefer using the history than using local storage.
If you really want to keep the data in memory, you can always use a store that is in a higher component (the root component for example) and keep the previous query over there. However you'll need to be careful about a lot of routing issues in such cases:
cache invalidation: the data changed on the server side in the mean time
user somehow gets back to a page with another table page number
loaded user presses the browser back button

React/Redux Where to save State

I am having trouble understanding some ReactJS and Redux principles,
In Redux we have a store and a set of reduceres that give your final state ( this part I get).
A Component receives props from their parent component, in case of Redux it passes the full state down with the Provider Component.
Now, lets assume this use case, I have my app state something like this :
auth : { name,id, ..etc} -> this is actually a JWT Token with a set of claims...
I am building a Container (Page) to be able to edit user profiles, the catch here , and where I am having trouble, I also want this page to handle a arbitrary user edit (in case admin is editing a account).
I am rendering my Page by using redux-router like this :
<Route path="/user" component={RequiresAuth(UsersPage) } >
<IndexRoute component={RequiresAuth(UsersOverview) }/>
<Route path="/user/overview" component={UsersOverview} />
<Route path="/user/account" component={AccountManagement} >
<IndexRoute component={RequiresAuth(AccountManagement) }/>
<Route path="/user/account/:userid" component={AccountManagement} />
</Route>
So reading the docs, I assume my props will have a userid which will override my default user if present.
Questions:
Is this approach correct? The Route Handling?
If I pass a userid param on the route, how do I proceed to load the user info and where? The way I see it, I need to dispatch an action, but I am not sure where to set the state , if on the store, or the component.
Also, Where would I load my user information? (constructor comes to mind)... or should it be in WillMount/WillReceiveProps?
Thank you.
If you really have a hard time to understand React/Redux principles i suggest you to try this tutorial :
https://github.com/happypoulp/redux-tutorial
It helped me a lot when i first started with React/Redux. By the way it's a bit hard to really answer your question because you re asking specific questions on a really specific case :)

Resources