I want to use the react router to show a page according to the first part of the URL, because the last part of the URL is holding an ID. How can I read out the last part, now I'm using string.split("/").pop()
URL
http://localhost:3003/profile/313a2333
Router
<Routes>
<Route path="/profile" element={<Profile/>} />
</Routes>
Define your Route like the following:
<Route path="/profile/:user_id">
Then you can get 2nd parameter in Profile component.
import { useParams } from 'react-router-dom';
const params: any = useParams();
const user_id = params.user_id;
If you don't care about the second path segment and only want to match according to the first segment then use a "*" wildcard matcher.
<Routes>
<Route path="/profile/*" element={<Profile/>} />
</Routes>
If you do need to capture this second path segment value, then provide a param name for it.
<Routes>
<Route path="/profile/:id" element={<Profile/>} />
</Routes>
Use the useParams hook to access route path params in the routed components.
const { id } = useParams();
Related
In short words, I want to know why this line does not work:
<Route path="/game/prepare/:id" element={ <Redirect to="/game/live/:id" /> } />
More description:
I have this url: www.mysite.com/game/prepare/1234 and I want it to instantly redirect to www.mysite.com/game/live/1234.
The implementation doesn't work because you are redirecting to the literal path string "/game/live/:id", the original id path parameter value is dropped. Redirect also ins't a valid react-router-dom#6 component. You should use the Navigate component, which is the spiritual successor to the RRDv5 Redirect component.
<Route
path="/game/prepare/:id"
element={<Redirect to="/game/live/:id" />}
/>
You'll need to create a custom component that can read the current route path params and render the appropriate redirection.
Example:
import { Navigate, useParams } from 'react-router-dom';
const RedirectToLiveGame = () => {
const { id } = useParams();
return <Navigate to={`/game/live/${id}`} replace />;
};
<Route
path="/game/prepare/:id"
element={<RedirectToLiveGame />}
/>
I am trying to run an onLoad event to get data from my db. I need to use a url parameter as a the prop to do this with but can't figure out how to access it.
I am using react-router v6, although in my package.json it is called react-router-dom.
Here is my setup
index.js
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/newrecipe" element={<RecipeForm />} />
<Route path="/recipe/:name" element={<RecipeDBTest />} /> //relevant line
</Routes>
</BrowserRouter>
Then in RecipeDBTest.jsx I need to grab the final parameter from my url string that looks like this:
http://localhost:3000/recipe/toast
So I would grab toast from URL string and pass to server with a fetch request on the RecipeDBTest.jsx page.
Just hoping for some advice/guidance here.
You can use useParams hook of react-router.
import {
useParams
} from "react-router-dom";
function Child() {
// We can use the `useParams` hook here to access
// the dynamic pieces of the URL.
let { name } = useParams();
return (
<div>
<h3>Name: {name}</h3>
</div>
);
}
let name = this.props.match.params.name
So I'm trying to display a 404 page if the path in my web app is undefined or nothing is rendered due to something having been deleted. For example, users can create books and the books id becomes the path to that page. But if a user deletes that book, the path will be undefined. So, if that happens id like to be able to make sure that any other user that tries to go onto that page is shown a 404 message.
For example, a link could be
'/home/undefined'
or
'/undefined/books'
To create any sort of "404 route", you simply have to add a route that matches any URL, and use it in a switch tag along with the valid routes. For instance:
<Switch>
<Route path ="/home" component={Home} />
<Route path ="/home/book" component={Book} />
<Route path ="/" component={FourZeroFour} />
</Switch>
You can also achieve the same effect by not using a Switch, and instead using exact on every route except the final one:
<Route path ="/home" component={Home} exact />
<Route path ="/home/book" component={Book} exact />
<Route path ="/" component={FourZeroFour} />
But what if you have a route that potentially matches both invalid and valid URLS, for instance:
<Route path ="/home/book/:bookId" component={SpecificBook} />
(where :bookId could be undefined)
In that case, you'll instead want to check the URL parameter's validity inside your component. For instance, your SpecificBook component might do the following:
const SpecificBook = ({ bookId } ) => {
if (bookId === 'undefined') return <Redirect to="/404" />;
// rest of component
}
You could also use history.push, but the Redirect tag will do more than just add a history entry; it will simulate a (server-side) redirect.
I will check the book_id first and the redirect if not found.
import {useHistory} from "react-router-dom"
function App() {
const history = useHistory();
if (!bookId) {
history.push("/404");
return null;
}
return <></>
}
In my render function I have
<Route path="/classes/:course" render={(match) => (
<Redirect to={`/classes/${match.params.course}/home`} />
)}>
<Route path="/home" component={Home} />
</Route>
For example if the param for "course" was "BIO1001", I want to redirect the page to "/classes/BIO1001/home" when I go to the page "/classes/BIO1001/". Previously I tried simply putting a Redirect tag with "from" and "to" but ran into the problem of the url actually going to "/classes/:course/home" instead of "/classes/BIO1001/home"
Also would the nested route with path="/home" go to "/classes/BIO1001/home"? I was unsure on how I can set a route where the path starts from the previous url (in this case starting from "/classes/:course/"
The first problem is right here:
render={(match) => ( ...
The render function gets a props object which contains a match property. Instead of destructuring the match property, what you are actually doing is assigning the whole props object to a variable match. So when you go to access match.params it won't be found.
You need curly braces around match in order to destructure it.
render={({match}) => ( ...
The second problem is the nesting of the two Route components. I get a warning:
Warning: You should not use <Route render> and <Route children> in the same route; <Route render> will be ignored
So based on that warning you can see that your Redirect is being entirely ignored since it comes from render. The child Route is seen as the render function for the classes Route.
I'm assuming you have various subpages of a course? And we want to force the URL to include "/home" if none is set? (Personally I would do the opposite and redirect "/home" to the course root URL).
Previously I tried simply putting a Redirect tag with "from" and "to" but ran into the problem of the url actually going to "/classes/:course/home" instead of "/classes/BIO1001/home"
Per the docs, you can use params in your Redirect, but only if it is inside a Switch.
Here's a sample code to do that:
const CoursePage = () => {
// you can access arguments from the props or through hooks
const { course, tab } = useParams();
// not sure how you want to handle the different tabs
return <div>Viewing Course {course}</div>;
};
const App = () => (
<BrowserRouter>
<Switch>
<Route path="/classes/:course/:tab"><CoursePage/></Route>
<Redirect from="/classes/:course" to="/classes/:course/home"/>
</Switch>
</BrowserRouter>
);
export default App;
Your nested routing is true i think. But you are rendering your Home component without any dynamic props. Try it like below:
<Route path="/classes/:course" render={(match) => (
<Redirect to={`/classes/${match.params.course}/home`} />
)}>
<Route path="/home" >
<Home someProps={someValue} />
</Route>
</Route>
Note: The Redirect element can be used without a containing Route element by providing a from property. In this case, you can just use the URL parameter tokens in both from and to, and they'll be carried over for you. For example, if you're using a Switch block...
<Switch>
{/* various app routes... */}
{/* redirect action */}
<Redirect from="/classes/:course" to="/classes/:course/home" />
<Switch>
I'm trying to implement React Router with query params like so http://localhost:3000/login?Id=1, I was able to achieve it only for my login route that too if I put path as http://localhost:3000/ which then redirects , however, I want to implement across the application. It matches nomatch route if I implement on other routes. This is how my index.js looks like, Can someone guide me how can i go about implementing all routes path including query params ?.
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route
exact
path={`/`}
render={() => {
if (!store.getState().login.isAvailable) {
return <Redirect to={`/login?Id=${Id}`} />
} else {
return <Dashboard />
}
}}
/>
<Route exact path={`/login`} component={Login} />
<Route exact path={`/signup`} component={SignUp} />
{Routes.map((prop, key) => (
<Route path={prop.path} key={key} component={prop.component} />
))}
<Route component={NoMatch} />
</Switch>
</BrowserRouter>,
document.getElementById('root')
)
There are two ways about to accomplish what you want.
The most basic way would be on each "page" or root component of each route, handle the parsing of query params.
Any component that is the component of a Route component, will have the prop location passed to it. The query params are located in location.search and that will need to be parsed. If you are only worried about modern browsers, you can use URLSearchParams, or you can use a library like query-string, or of course, you can parse them yourself.
You can read more in the react-router docs.
The second way of doing this, really isn't that different, but you can have a HOC that wraps around each of your "pages" that handles the parsing of the query params, and passes them as a list or something to the "page" component in question.
Here's an example of the basic way using URLSearchParams:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
// this is your "page" component, we are using the location prop
function ParamsPage({ location }) {
// you can use whatever you want to parse the params
let params = new URLSearchParams(location.search);
return (
<div>
<div>{params.get("name")}</div>
// this link goes to this same page, but passes a query param
Link that has params
</div>
);
}
// this would be equivalent to your index.js page
function ParamsExample() {
return (
<Router>
<Route component={ParamsPage} />
</Router>
);
}
export default ParamsExample;
EDIT: and to clarify, you don't need to do anything on your index.js page to make this work, the simple Routes you have should work fine.