React BrowserRouter - how to programmatically navigate to different routes? - javascript

I currently have this in my app.js file:
<BrowserRouter>
<div>
<Switch>
<Route exact path="/" component={CompOne}/>
<Route path="/two" component={CompTwo} />
</Switch>
</div>
</BrowserRouter>
In my CompOne, I want to programmatically navigate to CompTwo. I know I can use window.location to navigate to the /two path, but I would like to pass in some props to CompTwo.
How would I go about programmatically navigating from CompOne to CompTwo while passing in props?

One of the ways to do it is to make use of history.push() property so if you want to navigate to CompTwo you can do something like this inside CompOne :
this.props.history.push('/CompTwo');

Related

How can I use react router with a path of more than on / (no params)

I am trying to use react router using a composed path (ex: /demo/common). Common is not a param.
I would like to have something like this:
<Route
exact
path="/demo/page1"
component={Page1}
/>
<Route
exact
path="/demo/page2"
component={Page2}
/>
But when I try to access any of those routes it will just show me a white screen.
Thanks.
Add a parent route with path="/demo" and a parent component called ParentPage:
<Route path="/demo" component={ParentPage} />
Please note that parent route must not have exact prop, in order to do a nesting behavior.
Under ParentPage, you will have Page1 and Page2 as children:
<ParentPage>
<Route
path="/demo/page1"
component={Page1}
/>
<Route
path="/demo/page2"
component={Page2}
/>
</ParentPage>
It doesn't matter if the child component has exact prop or not.

How do I create a multiple page app with a login component in react?

Recently I've tried building a web platform trough React. Everything's fine, everything's work ecc.
But I've run in many problems when I tried to create a different page for the user login:
I already had Routes in my code, so when I tried to add other Routes to another js file they simply didn't work.
I have no clue how to do the authentication in react router, I've tried in many ways, followed many tutorials but nothing worked out.
<Switch>
<Route exact path='/' component={Feed}/>
<Route path="/user" component={Profilo}/>
<Route path='/explore-page' component={ExplorePage} />
<Route path='/events-page' component={EventsPage} />
<Route path='/calendar-page' component={CalendarPage} />
<Route path='/stats-page' component={StatsPage} />
<Route path='/form' component={FormPage}/>
<Route path="/user" component={Profilo}/>
<Route path="/user/:userId" component={Profilo} />
</Switch>
This is all the routes I'm currently using inside a div to get the react component rendered.
As I said before adding other routes in an upper file wouldn't give me a response.
So, in the end, I'm gonna ask you where should I put the route for the login and the home? In there or I should just moving everything?
Thank you in advance.
One simple way is adding the logic to handle authentication in your render function.
If the user is not authenticated. Redirect to the login page. Otherwise, go to your component
render() {
if (!this.props.isAuth) {
return (
<Switch>
<Route exact path="/" component={Login} />
<Redirect to="/" />
</Switch>
);
}
return (<Switch>
<Route
// your router
/>
</Switch>);
}

React nested route on root issue

When I try to have nested routes on my root route I run into a problem.
I have 3 "main" routes:
<Switch>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>
On my Home component I have a nested router like this:
<div>
<Route path="/" render={() => <div>Home</div>} />
<Route path="/test" render={() => <div>Test Route</div>} />
</div>
The Home component has a sidebar HOC which contains the Links.
<Sidebar>
<Link to="/">Home</Link>
<Link to="/test">Test</Link>
<Link to="/logout">Logout</Link>
</Sidebar>
When Im on my Root component and click the Test link, the route on the nested router changes to the Test component which is correct. Whenever I go the login and/or logout route it tries to display that in the nested router in the Home component
Any idea what is going wrong?
EDIT: I've tried the example #Tholle provided. Unfortunately it still doesn't work the way I want to. See this CodeSandBox I made to reproduce my problem.
your links need to point to "/home/testX" and the nested routes need to handle "/home/testX". Also you will need a route for "/home" in the root. I don't believe the Link component is scoped to the route in which it is called. Meaning that to link to "/test1" assumes that is the base route. However, the rendering of test1 actually takes place in the home component.
To put it another way: In order to get to /home/test1 you must first get the home component (/home) to render which can then render the route for test1 (/home/test1)
Here's the codesandbox
Here is an example that provides a bit more flexibility codesandbox. This one will require a redirect of "/" because it depends on the path being used and it needs to be "/home" not "/".
Hope this helps. Hope I got it all right.
The Switch component makes sure that only the first Route that matches is rendered. To stop <Route path="/" component={Home} /> from always being rendered, you can set the exact prop to true.
Example (CodeSandbox)
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>

Multiple ReactDOM.render calls with shared router context

I got two React components rendered like this.
ReactDOM.render(
<Router history={ browserHistory }>
<Route path='/items' component={ App }>
<IndexRoute component={ Home } />
<Route path='/items/:id' component={ Details } />
</Route>
</Router>,
document.getElementById('app')
);
And the second one, which is a sidebar.
ReactDOM.render(
<Sidebar />,
document.getElementById('sidebar')
);
I'd like to use the Link helper from react-router in the Sidebar component. However, I get the following error: "Uncaught Invariant Violation: Links rendered outside of a router context cannot navigate.". Which makes sense, because the sidebar is not within the router context like the first seen above.
Is there a way to share the router context with the sidebar?
I'd like to change the sidebar layout based on the route (and access the router object in this.props properly) and use Link as it should be.
I don't want to work my way around hacky approaches like history.pushState, or parsing location.path to change the sidebar's layout according to the corresponding route of items.
You should be able to just render your sidebar in its own <Router>. The important thing is that they share the same history instance (in this case, browserHistory).
When a <Router> mounts, it adds a listener to its history instance. When a history instance receives a new location, it notifies all of its listeners.
ReactDOM.render((
<Router history={browserHistory}>
<Route component={Sidebar} />
</Router>
) document.getElementById('sidebar')

Is it possible to pass a value from child route to its parent route with react router?

Let's say, I have a MainLayout with a header and a body. With react router, I render the component in the body.
...
<header></header>
<main>{this.props.children}</main>
...
This is my current router :
<Route component={MainLayout} onEnter={requireCordova}>
<Route path="/home" component={Home} />
<Route path="/settings" component={Settings} />
</Route>
My question is I want MainLayout to grab the title from one of its child (to fill the header), is it possible?
<Route component={MainLayout} onEnter={requireCordova}>
<Route path="/home" component={Home} title='homepage' />
<Route path="/settings" component={Settings} title='settings' />
</Route>
You can not communicate between components directly. You may want to use a shared store for such requirements - the most popular solution being Redux.
To address your specific problem of updating the title - there is a simple utility react-helmet that simplifies the process.
You can simply use the Helmet component inside any of your route components:
<Helmet title="My Title" /> and helmet will take care of updating your title. It works for other elements that go in HTML head as well - eg. meta, link, script tags etc.

Categories

Resources