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;
Related
the problem is the following. in the app.js is spelled out Routes and the home component. the home contains a navbar that navigates the site, only if you go to any page, it is drawn on top of the home. And if you switch to the home itself, it will be duplicated. Articles on the internet did not help, as did the addition of exact in route path.
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home/>}/>
<Route path="/settings/" element={<Settings/>}/>
<Route path="/login/" element={<Login/>}/>
<Route path="/register/" element={<Register/>}/>
</Routes>
<Home/>
</div>
)
home
export default class Home extends Component {
render() {
return (
<div>
<NavBar/>
<ChatMenu/>
</div>
);
}
}
an example of how it is written in the navbar
export const NavBar = () => {
return (<div className="navbar-cm">
<div className="nav_element">
<Link to="/home">
<img src={homeIMG} className="nav_element"/>
</Link>
</div>
and a few more similar ones
</div>);
};
Issue
You are rendering the Home component again once outside the routes, this is why it's rendered with all routes including twice when on the "/home" path that renders Home.
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home />} />
<Route path="/settings/" element={<Settings />} />
<Route path="/login/" element={<Login />} />
<Route path="/register/" element={<Register />} />
</Routes>
<Home /> // <-- always rendered below routed content
</div>
)
}
Solution
Remove the Home component that is out on its own outside the routes.
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home />} /> // <-- now only Home component rendered
<Route path="/settings/" element={<Settings />} />
<Route path="/login/" element={<Login />} />
<Route path="/register/" element={<Register />} />
</Routes>
</div>
)
}
Remove <Home /> from the router:
function App() {
return (
<div className="messenger">
<Routes>
<Route path="/home/" element={<Home/>}/>
<Route path="/settings/" element={<Settings/>}/>
<Route path="/login/" element={<Login/>}/>
<Route path="/register/" element={<Register/>}/>
</Routes>
</div>
)
// MAIN FUNCTION { APP START }
const App = () => {
return (
<Router>
<Nav />
<Switch>
<Route to="/" exact component={Home} />
<Route to="/login" exact component={Login} />
</Switch>
</Router>
);
};
export default App;
I just want that the Nav component renders everywhere except the login page ??
You can put it inside a route component along with the Home.
<Router> <Switch>
<Route path="/" exact>
<Nav />
<Home />
</Route>
<Route to="/login" exact component={Login} />
</Switch> </Router>
I have created routes in app.js and /, /create-receipt and /login routes are working fine but if I go to /signup route or any other route below /login it loads the Login component, if I remove login and signup component then the routes are working perfectly.
App.js:-
<Router>
<Header/>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/create-receipt" component={CreateReceipt} />
<Route Path="/login" component={Login} />
<Route Path="/signup" component={Signup} />
<Route path="/fast-food-receipt" exact component={FastFoodReceipt} />
<Route path="/fast-food-receipt/receipt-one" component={FastFoodReceiptOne} />
<Route path="/fast-food-receipt/receipt-two" component={FastFoodReceiptTwo} />
<Route path="/fast-food-receipt/receipt-three" component={FastFoodReceiptThree} />
<Route path="/fast-food-receipt/receipt-four" component={ReceiptFour} />
<Route path="/fast-food-receipt/receipt-five" component={FastFoodReceiptFive} />
<Route path="" component={NotFound} />
</Switch>
<Footer/>
</Router>
Login.js:-
const Login = () =>{
return(
login page
)
}
export default Login;
Signup.js:-
const Signup = () =>{
return(
signup page
)
}
export default Signup;
NOTE:- issue is coming when i use route component like this
<Route Path="/signup" component={Signup} />
<Route Path="/login" component={Login} />
working fine when i am using route component in this way:-
<Route exact path="/"><Home /></Route>
<Route path="/login"><Login /></Route>
<Route path="/signup"><Signup /></Route>
can some one tell why it is happening
I am trying to hide my header component on login page like following. But this is not working. Please guide how I can do this. Thanks in advance!
class App extends Component {
render() {
var auth = localStorage.getItem("auth")
console.log("app ===>", auth)
return (
<div className="App">
<Header />
<Router>
<LinkBar />
<main>
<Switch>
<Route path="/home">
<Protected cmp={Home}></Protected>
</Route>
<Route path="/shopping">
<Protected cmp={Products}></Protected>
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</main>
</Router>
</div>
)
}
}
export default App
Ideally this should work with jsx.
{ auth ? <Header auth={auth}></Header> : null }
or more elegant way
{ auth && (<Header auth={auth}></Header>) }
You can do something like bellow:
function App(){
return(
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route component={DefaultContainer} />
</Switch>
</Router>
);
}
const DefaultContainer = () => (
<Header />
<Router>
<Switch>
<Route exact path="/home" component={Home} />
<Route exact path="/shopping" component={Shopping} />
</Switch>
</Router>
)
This is our parent view:
http://localhost:8080/#/dashboard/
When I click on a link to Menu Navigation:
http://localhost:8080/#/dashboard/menu-navigation
This will load up the correct menu-navigation view, however if I refresh the app goes back to /dashboard instead of staying on menu-navigation.
From the main Routes.js
const Routes = () => (
<Provider store={store}>
<ConnectedRouter history={history}>
<Switch>
<Route path="/login" exact component={Login} />
<Route path="/redirect" component={FirebaseRedirector} />
<Route path="/restricted-access" component={RestrictedAccess} />
<Route path="/change-password/:hash?" component={ChangePassword} />
<Route path="/reset-password" exact component={ResetPassword} />
<Route path="/" component={Main} />
<Route path="*" component={NotFound} />
</Switch>
</ConnectedRouter>
</Provider>
);
export default Routes;
Note once you are logged in the Main component above is loaded:
render() {
return (
<Main
user={this.props.user}
signOut={this.signOut}
>
<Switch>
<Route
path="/dashboard/categories/unmatched-api/:id?"
component={CategoriesUnmatchedApi}
notExact
/>
<Route path="/dashboard/menu-navigation" exact component={MenuNavigation} />
<Route path="/dashboard/home-screen" exact component={HomeScreen} />
<Route path="/dashboard/categories/product-config" component={CategoryProductConfig} />
<Route path="/dashboard/categories/:category?" component={Categories} />
<Route path="/dashboard/playground" exact component={Playground} />
<Route path="/dashboard" exact component={Drafts} />
<Route path="/" exact component={Drafts} />
<Route path="*" component={NotFound} />
</Switch>
</Main>
);
}
Here is the state once you navigate to the MenuNavigation route
Then the state after refresh
Seems like react router is not respecting <Route path="/dashboard/menu-navigation" ?
I did notice after refresh that the Main.js route section gets hit 3 times, the first time the this.props.location is correct, however the next 2 times it's just /dashboard
Figured it out! We had a redirect to the /dashboard everytime.
Inside our login actions we had:
onAuthStateChange -> checkAuth which contained this:
dispatch(push(authDasboardView));
After removing the dispatch to authDashboardView, this fixed the problem!