I'm currently building a recipe book website based on ReactJS and react-router.
All my informations is saved in JSON and I'm handling all that using axios.
Now my question is, I have a grid with all my recipes, when I click on one is uses a Link to redirect me to another page, like this :
<Link to={'/' + name} className="recipe-styler" id={name}>
How can I redirect this so it will open a page and load the information of that.
I was thinking of just redirecting it to /detailedRecipe for example and parsing all the informations throught the Link, but I don't know if that is possible.
This is a combination of dynamic routing with react-router-dom and using match params.
First, let's say you have 3 routes in the app, List view, Details view and a fallback route (error page for example). It would look something like this:
<Router>
<Switch>
<Route exact path="/recipes" component={ListComponent} />
<Route path="/recipes/:id" component={DetailsComponent} />
<Route component={ErrorPage} />
</Switch>
</Router>
Now, you can set the links inside your grid to be something like this:
<Link to={`/recipes/${item.id}`} className="recipe-styler" />
Finally, when you click on the link, and router redirects to you the DetailsComponent, you can get the link id like this.
export class DetailsComponent extends React.Component {
componentDidMount() {
const { match } = this.props;
if (match) {
// This line is pseudocode.
// Use the id to get the item details from api, redux or wherever.
api.get(params.id)
}
}
render() {
...
}
}
Router will injects the match.params object when it resolves the route. Prop name from the params object depends on how you named it in the router declaration e.g.
<Route path="/recipes/:recipeId" component={DetailsComponent} /> // params.recipeId
<Route path="/recipes/:id" component={DetailsComponent} /> // params.id
Related
I have component with a button. I'd like a component to open another component in the new URL when the button is pressed. I don't want other components on the new page. I also want to pass data to a new component.
UPDATE:
<BrowserRouter>
<Link onClick={this.getData.bind(this)} to={{ pathname: "/test", data: this.state.data }}>Begin</Link>
<Switch>
<Route exact path="/test" component={Test} />
</Switch>
</BrowserRouter>
I wrote some code, but I have 2 problems:
How can I fetch data before route?
My component "Test" render on this page with previous components, I want only "Test" component on page
Please see react-router-dom for page to page navigation and passing data from one page to another.
You can use switch from react router dom along with routes. Please see documentation you will get to know about it.
I am trying to understand nested react routes. My current issue is that my link outputs undefined and also renders the component on the same view instead of loading just that component view.
Events.js
const data = {
"events":[
{
"id":"1234",
"name":"Meetup",
"description":"Tech meetup"
},
{
"id":"34234",
"name":"Test",
"description":"Events"
}
]
}
{data.events.map(event => (
<Link to={`/events/${data.events.id}`}>
<EventCard data={event} />
</Link>
))}
<Switch>
<Route path={`/events/:eventId`} render={(props) => <Event {...props} />}/>
</Switch>
How can I render the Event component when a user has clicked one of the event card. I can currently load both components on the same page but that is not my desired output. The expected path should be:
Expected:
Render only
Current:
Renders & on same page
At first you have got a problem here,
<Link to={`/events/${data.events.id}`}>
Since you are already mapping event object from data array, iterator event already holds event data. So you should change it like this;
<Link to={`/events/${event.id}`}>
Also I'd strongly recommend to use 'exact' prop in your routes for routing multiple endpoints from same root like this.
<Route exact path={`/events/:eventId`} render={(props) => <Event {...props} />}/>
See here for further information. Difference between exact path and path
You need to add id param to your event endpoint:
<Route path="/events/:id?" component={Event} />
Then in the Event you can check if id is present via props.match.params.id.
I am developing a dashboard application using React. I am having some issues understanding react-router. How can we use the dynamic route and render a component?
My app has a few static routes like /user, /profile and /dashboard. I am rendering User, Profile and Dashboard components for the routes. When the user logs in, the server will send JSON response which contains, user id, type, and other fields. I want to change the routing path to /dashboard/45 (45 is userId) for this user after a successful login. In the end, the Dashboard component will render different elements based on userId and userType.
<Route
path='/dashboard'
exact={true}
render={(props) => <Dashboard {...props} user={user} handleChildFunc=
{this.handleChildFunc}/>}/>
What is missing in this code? I am not sure what to google or which tutorial to follow. Thanks in advance.
This is what I use:
<Route exact path='/feed/:id' component={
(props) =>
<Feed
postId={props.match.params.id}
/>
}/>
Then the id can be accessed inside Feed using props.postId e.g.
constructor(props) {
super(props);
if (props.postId) {
// do something
}
}
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.
I don't think I'm fully understanding how to leverage react-router-redux. I understand that you can utilize:
<header>
<Link to="/" className="nav-link">Home</Link>
<Link to="/about-us" className="nav-link">About Us</Link>
</header>
<main>
<Route exact path="/" component={Home} />
<Route exact path="/about-us" component={AboutUs} />
</main>
By clicking on the links, the URL changes and different components are loaded. But how do I programmatically handle a change of component after a certain Action, for instance? I have an action that calls the server, manipulates the state, and then finally should re-route to a new Component. How does one handle this?
import { Redirect } from 'react-router-dom'
after the action recieves response from server and dispatched the response, listen if response from server is available and return redirect within your render function
render () {
.... //render logic
if (responseFromServer) {
<Redirect to='about-us' />
.... // rest of the render function and return statement
}
Update Based on your comment
I would do that in the about-us component.
const resetServerResponse = (serverResponse) => serverResponse = null // depends on typeof serverResponse could be empty string, bool or a set initial state.
......
dispatch(resetServerResponse)
so by the time you navigate back to the root / , responseFromServer is falsy andif (responseFromServer) {` will be skipped and not redirected.
If you are using react-router v4, you can import { push } from 'react-router-redux' and use it to dispatch any route like dispatch(push('/something')) in your actionCreator. No need to put that in your component logic.
See this example as well to get better clarity.
ReactRouterAuth Example