I'm working on a website on reactJS. I use radium and react router for the routes.
I have a lot of problems with routes...
On my main page there is a fixed nav bar menu with a link to the documentation page.
On this documentation page I also have this bar but to access to other links I have to click 2 times to get there..
class App extends Component {
render() {
return (
<Router history={hashHistory}>
<Switch>
<Route exact path="/" component={LandingPage}/>
<Route path="/documentation" component={DocumentationRoutes}/>
<Route path="/blog" component={OnContrustion}/>
<Route path="/contactus" component={OnContrustion}/>
</Switch>
</Router>
);
}
}
export default App;
Here is the DocumentationRoutes:
class DocumentationRoutes extends Component {
render() {
return (
<Router history={hashHistory}>
<Switch>
<Route path="/documentation" component={Documentation}/>
<IndexRoute component={Documentation} />
</Switch>
</Router>
);
}
}
export default DocumentationRoutes;
and the documentation :
class Documentation extends Component {
render() {
return (
<VerticalLayout>
<StretchLayout>
<NavBar />
</StretchLayout>
<StretchLayout margin="20">
<CenterLayout>
<SubTitle>Documentation</SubTitle>
</CenterLayout>
<DocMenu />
</StretchLayout>
</VerticalLayout>
);
}
}
export default Documentation;
Is it the right way to use react router ?
What can I do to be redirected after only one click ?
On the first click, the url change correctly but not the page.
Thanks,
You only need to use the Router component in the initial routes definition. Your DocumentationRoutes component should be:
Also in react-router v4 IndexRoute no longer exists.
class DocumentationRoutes extends Component {
render() {
return (
<Switch>
<Route path="/documentation" component={Documentation}/>
<Route component={Documentation} />
</Switch>
);
}
}
export default DocumentationRoutes;
Related
Well, I defined the react router as follows:
<BrowserRouter>
<Routes>
<Route path="/" exact element={<Home/>} />
<Route path="details/:id" element={<ViewNote/>}/>
</Routes>
</BrowserRouter>
and I called it like this in the class component:
import React, { Component } from 'react'
export default class ViewNote extends Component {
componentDidMount(){
console.log(this.props.match.params.id);
}
render() {
return (
<div>
<h2>{this.props.match.params.id}</h2>
</div>
)
}
}
But it shows match undefined in the console!!!
how to solve it??
thanks.
I followed the Auth0 React Authentication guide written here:
https://auth0.com/blog/complete-guide-to-react-user-authentication
And implemented the ProtectedRoute component as outlined in the tutorial:
import React from "react";
import { Route } from "react-router-dom";
import { withAuthenticationRequired } from "#auth0/auth0-react";
import { Loading } from "../components/index";
const ProtectedRoute = ({ component, ...args }) => (
<Route
component={withAuthenticationRequired(component, {
onRedirecting: () => <Loading />,
})}
{...args}
/>
);
export default ProtectedRoute;
But now I am having an issue with the ProtectedRoute component that doesn't exist if I use withAuthenticationRequired directly in the export statement of the component that I am trying to protect. I have a web app that contains routes like the following:
<Router>
{isAuthenticated && <Header />}
<Switch>
<Route exact path='/'>
{isAuthenticated ? <Redirect to="/home" /> : <LandingPage />}
</Route>
<ProtectedRoute path='/home' component={Home}/>
<ProtectedRoute path='/events' component={Events}/>
<ProtectedRoute path='/dates' component={Dates}/>
</Switch>
</Router>
And my Home component contains something like the following:
function Home(){
return <div className="home-page">
<Sidebar />
<ProtectedRoute path={"/home/dogs"} component={Dogs}/>
<ProtectedRoute path={"/home/cats"} component={Cats}/>
</div>
}
export default Home;
The bug also happens when the Home component doesn't use ProtectedRoute like so:
function Home(){
return <div className="home-page">
<Sidebar />
<Route path={"/home/dogs"} component={Dogs}/>
<Route path={"/home/cats"} component={Cats}/>
</div>
}
export default Home;
I can't explain why it happens, but it prevents the state within the Sidebar component from changing the sidebar's appearance and rendered components.
Here is a link to a codesandbox on how the sidebar should work (no auth0).
https://codesandbox.io/s/react-routing-problem-2efic
When using ProtectedRoute as in the code above, the active class on the navbar links changes, but the rest of the content stays the same.
However, if I instead take the ProtectedRoute off of the Home component, but use withAuthenticationRequired on the export of the Home component, like so:
export default withAuthenticationRequired(Home, {
onRedirecting: () => (<div>Redirecting you to the login page...</div>)
});
and
<Route path='/home' component={Home}/> //instead of ProtectedRoute
Then everything works as it should.
My questions are:
Why is the ProtectedRoute component behaving differently from when withAuthenticationRequired is at the export level?
Do I need to protect routes that are nested within a protected route?
Thanks for any help!
I am creating a workarea with a side navigation and a header bar. But if the user is not logged in, I want to direct them to the login page.
The main component is as follows
class App extends Component {
render() {
return (
<Provider store={store}>
<Router history={history}>
<div>
<Route exact path="/login" component={Login}/>
<Route exact path="/" component={Reporter}/>
</div>
</Router>
</Provider>
);
}
}
export default App;
The Reporter component looks like this:
class Reporter extends Component {
render() {
return (
<Router history={history}>
<div className="reporter-container">
<SideNav/>
<Switch>
<Route exact path="/reporter" component={WorkArea}/>
<Route exact path="/reporter/page1" component={Page1}/>
<Route exact path="/reporter/page2" component={Page2}/>
<Route exact path="/" component={WorkArea}/>
</Switch>
</div>
</Router>
);
}
}
export default Reporter;
In both examples, I have included react-router-dom and history:
import { Switch, Route, Router } from 'react-router-dom'
import history from '../utils/history'
SideNav looks like this:
class SideNav extends Component {
render() {
return (
<div className="side-nav">
<div className="side-nav-item">
<i className="fas fa-file side-nav-icon"></i><Link to="/reporter/page1">Page1</Link>
</div>
<div className="side-nav-item">
<i className="fas fa-male side-nav-icon"></i><Link to="/reporter/page2">Page2</Link>
</div>
</div>
);
}
}
export default SideNav;
The login works fine, but the when I select a side navigation, the URL is going to /reporter/page1, but it is just bank. I think this is because it is looking in the App component routing and finding nothing. I suppose I could move everything to the App component and set the visibility of the side nav bar to none. Does anyone know of the best practice for this pattern?
You shouldn't have two routers, the best practice is to handle all of your routing in a single place. Your code is not working because the router can't find the appropriate component to render for the `reporter/page1' route because it's looking in the first router it finds.
You need to handle all of your routing in a single place. This will also allow you to easily handle the redirection to the /login route with the <Redirect /> component from react-router-dom
You can do it like this
class SomeComponent extends Component {
...
redirectIfNotLoggedIn = () => {
return this.state.isLoggedIn && <Redirect to={'/login'} />
}
render() {
return (
<div>
{this.redirectIfNotLoggedIn()}
<-- Actual component code -->
</div>
)
}
}
I am new to the react-redux. Here I am using the following thing for showing the 404 not found if the given route does not matches.
now, In this
My App.js
class App extends React.Component {
render() {
return (
<Provider store={store}>
<div className="container-fluid">
<Header />
<Main />
</div>
</Provider>
)
}
}
My Main.js
render() {
return (
<div>
<Router history={history}>
<div>
{this.props.isFetching && <Loading />}
<Switch>
<PrivateRoute exact path="/" component={LandingScreen} />
<PrivateRoute exact path="/quiz-setup" component={QuizSetupMain} />
<PrivateRoute exact path="/quiz-questions" component={FetchedQuestionComponent} />
<Route exact path="/login" component={LoginComponent} />
<Route exact path="/*" component={NotFound} something="foo" />
</Switch>
</div>
</Router>
</div>
)
}
}
NotFound.js
import React from 'react';
export default class NotFound extends React.Component {
render() {
return (
<h1>Something Went Wrong</h1>
);
}
}
Now , here when user hits any route which is not present then it shows that 404 not found, but it also shows the header part as well. I know that , its because I have rendered both header and main in the app.js file, and not found is in the main, but is there any way to not show that header , if the route is not matched . thanks
You can add function, which returns Component after Header.
for example:
const withHeader = (Component) => {
return class withHeaderComponent extends React.Component{ render() { return (<div><Header /><Component /></div>)}}
}
after creating this function, you can use it like,
<Route exact path="/login" component={withHeader(LoginComponent)} />.
So you are able to add header for Routes you want.
<Route component={NotFound}/>
Now your 404 will be without Header !
Let me know if you face difficulties.
You can use the component of dynamic components.
The idea is, every route path that is called, navigates through a common component which invokes suitable behaviour based on the component called. For example -
<PrivateRoute exact path="/" component={CustomComponent} />
and then pass props accordingly to determine, which screen has to render the header component.
So, essentially, your code will look something like this -
class App extends React.Component {
render() {
return (
<Provider store={store}>
<div className="container-fluid">
<Main />
</div>
</Provider>
)
}
}
and the <Header/> component will be called in custom component based on appropriate conditions that you put forward
Hope it helps :)
You can also use a wildcard to redirect people to not found page the route is not accessible.
import React from 'react';
import { Switch } from 'react-router';
import { BrowserRouter , Route ) from 'react-router-dom;
import NotFound from './NotFound';
const routes = (
<BrowserRouter>
<Switch>
<Route path="*" component={NotFound}/>
</Switch>
</BrowserRouter>
)
Could anyone help me with this question?
I'm a bit lost when using different routes containing subroutes.
I am trying to add routes with different paths.
I would like to have a default route with all the features and an alternate Event route separately.
From now on I am grateful for the attention and thank you very much.
index.js
Contains the two different routes. Layout and Event.
The Route Layout contains another Routes component inside.
const Root = (
<BrowserRouter>
<Route component={App}>
<Route component={Layout}/>
</Route>
<Route path="/event/:id" component={Event}/>
</BrowserRouter>
)
ReactDOM.render(Root , document.getElementById('root'));
App.js
Component to be loaded. Layout or Event
class App extends Component {
render() {
const { children } = this.props;
return (
<div>{children}</div>
);
}
}
export default App;
RouterLayout.js --> This route is a subroute that is inside the Layout
const Router = () => (
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/about' component={About}/>
</Switch>
)
export default Router
Layout.js
class Layout extends Component {
render() {
const { children } = this.props;
return (
<Content className="column is-8 content-page">
<RouterLayout/>
<div>{children}</div>
</Content>
);
}
}
export default Layout;
I was able to solve this way
<BrowserRouter>
<div>
<Route exact path="/page/*" component={Layout}/>
<Route exact path="/event/:id" component={EmptyLayout}/>
</div>
</BrowserRouter>