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.
Related
I have simple app with react-router v5. In App component I have switch like this:
<Switch>
<Route path="/post">
<Post />
</Route>
<Route path="*">
<Error />
</Route>
</Switch>
In other component I have Link with path like this:
<Link to={{ pathname: `/post?id=${message.id}`, state: { message } }}>text</Link>
Now, Error component is only logging the pathname and state from useLocation() hook, Post component is showing pathname in HTML tag.
When I click the link, the component that is rendered, is 'Error', it console.log correct path name ('.post?id=123'), and it logs correct state. Address in browser is correct, but Post component is not rendered. When I refresh browser, then correct component is rendered. I mean when i refresh being on post?id=123, then 'Post' is rendered, but when I try to click link directing to 'post?id=123', 'Error' is rendered. If I use <Link to={/post?id=${message.id} /> without state, routing is working fine.
Here's codesanbox, it seems the issue is this part: to={{pathname: '/post?id=${message.id}, state: {message}}, when I remove ?id=${...} it works fine. But still I would like to have this id there.
It seems I shouldn't use query string when using object as 'to' parameter. If someone needs to include query string, there is search parameter in 'to' object.
I’m using the last release of React Router and I want to know what is the best solution to show different component that are nested in a parent component.
I’ll try to explain myself better.
I have a route R with path /r1.
This route loads component A.
Component A has inside others 3 components B, C and D that I should show in the same page with component A only when the user press a specific button in component A.
So I want to be able to add a description in route R to manage this. For example to show component B the router could be /r1/b.
Now I did this with a state variable inside component A but I think should be better if I can use some React Router property.
Thanks
You can create nested routes component, and it will manage nested routes.
export default function NestedRoutes() {
return (
<Switch>
<Redirect exact from={"/r1"} to={`/r1/A`} />
<Route path={`/r1/A`}>
<ComponentA />
</Route>
<Route path={`/r1/B`}>
<ComponentB />
</Route>
// Or to some not found component
<Redirect to="/r1/A" />
</Switch>
);
}
I'm using Switch with my route entries. The problem was that I didn't know how to render a component that I wanted to pass by props to another component.
I added a prop component to my parent component A and in my route I wrote something like this:
<Route path="/r1/hub/A" render={() => <A /> //this render only A
<Route path="/r1/hub/A/B" render={() => <A component={B} /> //this render A with B
In component A I used React.createElement to render component B with others properties that component A has to inject.
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
I started using react router v4 and I have 2 questions. Ive been researching and reading about router 4 but cant explain why the following happens:
ps. I have included only code I thought is relevant, please let me know if I should dd more.
<BrowserRouter>
<div>
<Route path="/" component={PostsIndex} />
<Route path="/posts/new" component={PostsNew}></Route>
</div>
</BrowserRouter>
PostsIndex:
<Link to="/posts/new">Add a Post</Link>
1. What happens with my code below is on route '/' I am being shown PostsNew Component. When I manually put url to '/posts/new' both components are being rendered - PostsIndex and PostsNew which is intended. HOWEVER, when im on '/' and click on my Link (with path: /posts/new) nothing happens. The PostsNew component is not being rendered unless I refresh the page (so the url already changed after I click the link but I need to refresh it-url stays same- and only then will the nested component being rendered). Why does this happen?
Another question:
Below I want to achieve the opposite- NOT nesting routes. When I use switch and put the most specific route first, it works. Also when I click on the Link, the PostsNew is being rendered without the need to refresh. My question is just to understand routing better:
I would expect in my code below, both components being rendered on /posts/new - but here the PostsNew component is NEVER being rendered. Why?
Why is my Link working when I use Switch and if I dont I must manually refresh/put url? Thanks!
If you only want a specific path to render you need to add an exact attribute to the Routes:
<Route exact path="/" component={PostsIndex} />
<Route exact path="/posts/new" component={PostsNew}/>
I have a React MaterialUI AppBarcomponent with property title , that I am changing based on the value returned by window.location.pathname. So as the page/url changes, the title will change with it. Looks something like below:
<AppBar
title={this.renderTitle()}
/>
renderTitle() {
if (window.location.pathname === '/home'
return 'home';
} else if (window.location.pathname === '/login'
return 'login';
}
The issue I am running into is that renderTitle() does not get executed if a different component (so not the AppBar) causes the page/url change.
E.g. another separate React component on the page triggers the page to change, which I'd hoped with trigger renderTitle(), but it doesn't... thus the title property never updates. So if I am navigating from /home to /login, the following will happen:
pathname is /home
user presses a button which runs a function, submit(), which is used to change the page w/ react-router
renderTitle() is run at this point, but window.location.pathname is still returning the previous page
submit() changes the page to /login
window.location.pathname is now correctly set to /login, but it is too late as renderTitle() has already been run
any help is appreciated, thanks
The best way is to use react-document-title library.
From documentation:
react-document-title provides a declarative way to specify document.title in a single-page app.
This component can be used on server side as well.
If your component that renders AppBar is an actual route you can just read the pathname from the props that react router injects.
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
<Route path="messages/:id" component={Message} />
</Route>
</Route>
</Router>
For example in App, About, Inbox and Message you have access to the router props. And you can also pass the props to their children.
render() {
return (
<AppBar
title={this.renderTitle(this.props.location.pathname)}
/>
);
}
And in your function just use the parameter to return the correct result. Now because you are using props your component will update automatically when they change.