So the problem I am facing is this. When I load the page, the stylings of the Header component are not being rendered, but when I remove the load Logic they are. The problem might lie in Header component BCS it is in every Route except Login. I need it to be rendered on every path except Login. Where the error could be?
const Cart = loadable(
() =>
new Promise((resolve, reject) =>
setTimeout(() => resolve(import("./components/Cart/Cart")), 100)
),
{
fallback: <div className="login__loader">
<img src='./audie/Glowing ring.gif' alt= ''></img>
</div>
}
);
const Book = loadable(
() =>
new Promise((resolve, reject) =>
setTimeout(() => resolve(import('./components/Home/Book')), 100)
),
{
fallback: <div>Loading...</div>
}
);
const App=()=> {
return (
<React.Fragment>
<Switch>
<Route exact path='/'>
<Header />
<Home />
</Route>
<Route path="/cart">
<Header />
<Cart />
</Route>
<Route path="/stripecontainer">
<Header />
<StripeContainer />
</Route>
<Route path='/book/:bookId'>
<Header />
<Book />
</Route>
<Route path='books'>
<Books/>
</Route>
<Route path='/forgotpassword'>
<ForgotPassword />
</Route>
<Route path='/passwordreset/:resetToken'>
<ResetPassword />
</Route>
<Route exact path='/register'>
<Register />
</Route>
<Route path='/login'>
<Login />
</Route>
</Switch>
</React.Fragment>
);
}
export default App
So the problem was in CSS.
Styles from Header.css needed to be in App.css. I don't know why
Related
how it is possible to remove this routing in a separate component? I tried to do it through the map but it did not work
I want only one route to remain and when you click on a certain link, 'path' changes in it
const Home = ({ code }) => {
return (
<div className="wrapper__flex_main">
<TheNav {...code} />
<Routes>
<Route path='/' element={<Main code={code} />} />
<Route path='/search' element={<TheSearchTrack code={code} />} />
<Route path='/likes' element={<Likes code={code} />} />
<Route path='/artist' element={<Artist code={code} />} />
<Route path="/genre/:id" element={<GenreTemplate code={code} />} />
<Route path="/artist/:id" element={<ArtistPages code={code} />} />
<Route path="/genretrack/:id" element={<GenreTrack code={code} />} />
<Route path="/track/:id" element={<Track code={code} />} />
</Routes>
</div>
)
}
export default Home
const navigate = useNavigate();
...
const loginHandler = () => {
... business logic ...
// if logic true
navigate('navigate-path', { replace: true }); // redirect!!!
};
You can use something like this , this prevent user navigation to other pages
I have a React site with three different routes, and I want it to automatically display the first one, which is called Home, when a user enters the site. Here is the code I have in App.js:
<Router>
<Navigation />
<Switch>
<Route path="/hypstats" exact component={() => <Home />} />
<Route path="/hypstats/auctions" exact component={() => <AuctionViewer />} />
<Route path="/hypstats/bazaar" exact component={() => <BazaarViewer />} />
</Switch>
</Router>
And here is the Navigation component:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import "../App.css"
function Navigation(props) {
return (
<div className="navbar">
<Link className="navlink" to="/hypstats">HypStats</Link>
<Link className="navlink" to="/hypstats/auctions">Auctions</Link>
<Link className="navlink" to="/hypstats/bazaar">Bazaar</Link>
</div>
)
}
export default Navigation;
To make any view as the default view you could include the following into your Navigation
<Route path="/" exact component={() => <Home />} />
Or you could write as below:
<Redirect from="/" to="/hypstats"} />
<Router>
<Navigation />
<Switch>
<Route path="/hypstats" exact component={() => <Home />} />
<Route path="/hypstats/auctions" exact component={() => <AuctionViewer />} />
<Route path="/hypstats/bazaar" exact component={() => <BazaarViewer />} />
**<Route path="/" exact component={() => <Home />} />**
</Switch>
</Router>
We use the basename attribute to tell the basename of the site. So that in the next routes, we would not have to set basename, here /hypstats, manually every time we add a new route. React Router manages it by itself.
<Router basename="/hypstats">
<Navigation />
<Switch>
<Route path="/" exact component={() => <Home />} />
<Route path="/auctions" exact component={() => <AuctionViewer />} />
<Route path="/bazaar" exact component={() => <BazaarViewer />} />
</Switch>
</Router>
Run this somewhere in your App component.
history.push({
pathname: '/hypstats',
});
You are using "react-router-dom" so you can import:
import { useHistory } from "react-router-dom";
And then you can use:
const history = useHistory();
So whenever user enters your react application it will open the '/hypstats'.
You could do this in a useEffect.
I had a web app where you had to be authentified to see the content. First thing you saw entering the website was the Keycloak login page rendered in Login.js, once you were logged in, you had access to Routes.js. Now I have to add public routes to this same application and I'm not sure how to proceed. Here's what I have so far.
Index.js
<Suspense fallback='loading'>
<BrowserRouter>
<PublicRoutes/>
</BrowserRouter>
</Suspense>
PublicRoutes.js
return (
<Switch>
<Route exact path="/" render={() => <Redirect to="/signup"/>}
/>
<Route exact path="/signup" render={() => <SignupPage header={HeaderNav}/>}
/>
<Route exact path="/login" render={() => <Login/>}
/>
</Switch>
);
Login.js
if(this.state.keycloak) {
if(this.state.authenticated) return (
<Routes keycloak={this.state.keycloak}/>
); else return (<div>Unable to authenticate!</div>)
}
return (
<div>Loading, please wait...</div>
);
Routes.js
<Switch>
<Route exact path="/" render={() => <Redirect to="/home"/>}
/>
<Route exact path="/home" render={() => <HomePage header={HeaderNav} sidebar={Sidebar}/>}
/>
<Route exact path="/catalog" render={() => <CatalogPage header={HeaderNav} sidebar={Sidebar}/>}
/>
<Route exact path="/query" render={() => <QueryPage header={HeaderNav} sidebar={Sidebar}/>}
/>
<Route exact path="/workshop" render={() => <WorkshopPage header={HeaderNav} sidebar={Sidebar}/>}
/>
<Route exact path="/dashboard/stats" render={() => <StatsPage header={HeaderNav} sidebar={Sidebar} keycloak={this.props.keycloak}/>}
/>
<Route exact path="/dashboard/keys" render={() => <KeysPage header={HeaderNav} sidebar={Sidebar} keycloak={this.props.keycloak}/>}
/>
<Route exact path="/dashboard/consumption" render={() => <ConsumptionPage header={HeaderNav} sidebar={Sidebar} keycloak={this.props.keycloak}/>}
/>
<Route exact path="/faq" render={() => <HelpPage header={HeaderNav} sidebar={Sidebar}/>}
/>
<Route exact path="/contact_us" render={() => <ContactPage header={HeaderNav} sidebar={Sidebar}/>}
/>
<Redirect from="/login" to="/home"/>
</Switch>
What I'd like is that the Routes.js file takes over the PublicRoutes.js file when the user is authentified. Right now, when the user logs in, he can still only see the public routes content.
Try lifting state up. Maybe Index.js can switch between 2 sets of routers?
You can pass state (Keycloak object) or callbacks (handleLogin) for Login.js if you need to
Example:
render() {
const { keycloak, authenticated } = this.state;
return
<div>
{authenticated ? (
<Secured keycloak={keycloak} />
) : (
<Public handleLogin={this.handleLogin} />
)}
</div>
}
Another post to ask you about a "situation" I am having, which is disappointing as my Router is creating too many refreshs and for the point is actually not to have to refresh part of the page by using React.
I would like the following :
When I go to './' and there is no user connected it shows a homepage (without header and footer)
When I go to './' and I am connected or any other link whether I am connected ot not it should show the relevant page with a Header and a Footer.
So the fact of being not connected does not show header/footer is only true for the './' address.
How I solved it and it is not satisfying because it seems my header is rerendering all the time I change pages even between two pages with Router....
I have a first Router, the AppRouter :
const AppRouter = () => (
<BrowserRouter>
<div className="content">
<Switch>
<Route path="/" component={Index} exact={true} />
<SubRouter />
</Switch>
</div>
</BrowserRouter>
);
export default AppRouter;
My index is like that :
export class Index extends React.Component {
render() {
if (this.props.user){
return (
<SubRouter />
)
} else {
return (
<Homepage />
)
}
}
}
So if no user the Homepage is showing if user it goes back to the SubRouter.
SubRouter is like that :
export class SubRouter extends React.Component {
(...)
render(){
return (
<div className="fullpage">
{this.state.inboxOpen ? <Inbox closeInbox={this.closeInbox} oneUserInboxId={this.state.oneUserInboxId} /> : undefined }
<Header openInbox={this.openInbox} closeInbox={this.closeInbox} />
<Switch>
<Route path="/" component={Dashboard} exact={true} />
<Route path="/admin" component={Admin} exact={true} />
<Route path="/account" component={Account} exact={true} />
<Route path="/settings" component={Settings} exact={true} />
<Route path="/faq" component={Faq} exact={true} />
<Route path="/cgv" component={Cgv} exact={true}/>
<Route path="/legal" component={Legal} exact={true}/>
<Route path="/login" component={Login} exact={true}/>
<Route path="/signup" component={Signup} exact={true}/>
<Route path="/notifications" render={() => (<Dashboard notifications={true} />)} exact={true} />
}} />
<Route path="/reset-password/:token" component={ResetPassword} />
<Route path="/forgot_password" component={ForgotPassword} exact={true} />
<Route path="/post/:postId" component={OnePost} />
<Route path="/*" component={NotFound} />
</Switch>
<Footer />
</div>
)
}
}
So this code is "working" but somehow we can see rerenders that should not happen, I am open to any idea to optimize this. Thanks in advance !
Problem was coming from here :
const AppRouter = () => (
<BrowserRouter>
<div className="content">
<Switch>
<Route path="/" component={Index} exact={true} />
<SubRouter />
</Switch>
</div>
</BrowserRouter>
);
export default AppRouter;
Should not have rerendered SubRouter here as it is already rendered in HomePage. Good code is :
const AppRouter = () => (
<BrowserRouter>
<div className="content">
<Switch>
<Route path="/" component={Index} exact={true} />
</Switch>
</div>
</BrowserRouter>
);
export default AppRouter;
I have problem with nested routing.
On the normal site I have other urls than on the / admin page and i have different design and html.
I prepared this sample routing but after the page refreshes, the page gets white without any error.
Can I ask for a consultation what did I do wrong?
APP COMPONENT
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="container">
<Route exact path="/" render={(props) => (
<Page {...props} data={data} />
)} />
<Route exact path="/admin" render={(props) => (
<Admin {...props} data={data} />
)} />
</div>
</BrowserRouter>
);
}
}
PAGE COMPONENT
class Page extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Header />
<Route exact path="/" render={(props) => (
<Home {...props} videosJson={this.props.data} />
)} />
<Route path="/about" component={ About } />
<Route exact path="/video" render={(props) => (
<VideoGallery {...props} videosJson={this.props.data} />
)} />
<Route path="/video/:id" render={(props) => (
<VideoPage {...props} videosJson={this.props.data} />
)} />
<Route exact path="/photo" render={(props) => (
<PhotoGallery {...props} videosJson={this.props.data} />
)} />
<Route path="/photo/:id" render={(props) => (
<PhotoPage {...props} videosJson={this.props.data} />
)} />
<Route path="/contact" component={ Contact } />
<Footer />
</div>
</BrowserRouter>
)
}
}
ADMIN COMPONENT
class Admin extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Route exact path="/admin" render={(props) => (
<Dashboard {...props} />
)} />
</div>
</BrowserRouter>
)
}
}
Your React application which uses React-Router should only have one instance of a Router defined, as stated in the documentation:
The common low-level interface for all router components. Typically
apps will use one of the high-level routers instead
The error you are getting is because you are defining additional routers (in your case there are multiple instances of BrowserRouter) in your Page and Admin components.
Also some of your Routes are ambiguous e.g.
<Route exact path="/" render={(props) => (
<Page {...props} data={data} />
)} />
and:
<Route exact path="/" render={(props) => (
<Home {...props} videosJson={this.props.data} />
)} />
One Route says that root ('/') should navigate to the Page component, the other says that root should navigate to the Home component, hence there is a conflict. Make sure the routes are unique.
I change my approach to this situation but dont work. Url /admin load Header and Footer component although he should not and component Dashboard not load.
Any sugestion?
<BrowserRouter>
<div className="container">
<Page>
<Header />
<Route exact path="/" render={(props) => (
<Home {...props} videosJson={data} />
)} />
<Route path="/about" component={ About } />
<Route exact path="/video" render={(props) => (
<VideoGallery {...props} videosJson={data} />
)} />
<Route path="/video/:id" render={(props) => (
<VideoPage {...props} videosJson={data} />
)} />
<Route exact path="/photo" render={(props) => (
<PhotoGallery {...props} videosJson={data} />
)} />
<Route path="/photo/:id" render={(props) => (
<PhotoPage {...props} videosJson={data} />
)} />
<Route path="/contact" component={ Contact } />
<Footer />
</Page>
<Admin>
<Route exact path="/admin" render={(props) => (
<Dashboard />
)} />
</Admin>
</div>
</BrowserRouter>
Admin Component:
class Admin extends React.Component {
render() {
console.log("ADMIN:", this.props);
return (
<div className="row">
<h1>ADMIN</h1>
{this.props.children}
</div>
)
}
}
Page Component:
class Page extends React.Component {
render() {
console.log("PAGE:", this.props);
return (
<div>
{this.props.children}
</div>
)
}
}