Different forms of navigation on different pages | non-global navigation - reactjs

I currently have a homepage, where I would like to have a sidebar featuring Home, Login, SignUp.
I have a login and sign up page, where I want a regular navbar for which I have right now.
Currently, as I am building the framework for my app, the regular navbar is currently global.
How can make this unglobal, and specify the pages I want the navbar on? As I would like it removed from my homepage so I can build the sidebar accordingly.
App.Js
return (
<div className="App">
<nav className="navbar navbar-expand-lg navbar-light fixed-top">
<div className="container">
<Link to = '/'>
<div>
<img src ={Logo} alt='Logo' className='Logo'/>
</div>
</Link> <div className="collapse navbar-collapse" id="navbarTogglerDemo02">
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link className="nav-link" to={"/sign-in"}>Login</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to={"/sign-up"}>Sign up</Link>
</li>
</ul>
</div>
</div>
</nav>
<div className="auth-wrapper">
<div className="auth-inner">
<Routes>
<Route path='/' element={<Home />} /> // components on element prop
<Route path="/sign-in" element={<Login />} />
<Route path="/sign-up" element={<SignUp />} />
</Routes>
</div>
</div>
</div>
);
}
export default App;
Home
render() {
return (
<div style={{ display: "flex" }}>
<Sidebar />
<h1>Sidebar page</h1>
</div>
);
}
}
Sidebar
//sidebar.js
import React, { Component } from "react";
export default class Sidebar extends Component {
render() {
return (
<div className="sidebar-container">
<div className="sidebar">
<a className="sidebar-link">Link</a>
<a className="sidebar-link">Link</a>
<a className="sidebar-link">Link</a>
</div>
</div>
);
}
}

Related

I should refresh browser to render my component using Routes | ReactJS

I have a menu with some routes. I want to show the component that correspond to his route while clicking on the menu. The issue is that, on the click, it changes me the url on my browser but the component displayed doesn't change. I have to refresh manually the page to render the good component. But my aim is to display the good component on the click without refreshing the page.
Here is my Menu.js code :
<Router>
<Link to={'/'} className="nav-link" id="homeLink">
<div className="tableElement active" id="home">
<FontAwesomeIcon icon={ faHome } className="icon"/>
</div>
</Link>
<Link to={'/org'} className="nav-link" id="orgLink">
<div className="tableElement" id="organisation">
<FontAwesomeIcon icon={ faTasks } className="icon"/>
</div>
</Link>
<Link to={'/users'} className="nav-link" id="usersLink">
<div className="tableElement" id="user">
<FontAwesomeIcon icon={ faUsers } className="icon"/>
</div>
</Link>
</Router>
Here is my render method App.js code :
render() {
return (
<Router>
<div className="App">
<LeftMenu/>
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/org'
render={ (routeProps) => ( <Organisations {...routeProps} /> ) }
/>
<Route path='/users'
render={ (routeProps) => ( <UserTable {...routeProps} /> ) }
/>
</Switch>
</Router>
);
}
Thanks for your help !
I resolved my issue, I just made a big mistake, my bad.
I just deleted <Router> tags that wrapped my code in Menu.js.
<Link to={'/'} className="nav-link" id="homeLink">
<div className="tableElement active" id="home">
<FontAwesomeIcon icon={ faHome } className="icon"/>
</div>
</Link>
<Link to={'/org'} className="nav-link" id="orgLink">
<div className="tableElement" id="organisation">
<FontAwesomeIcon icon={ faTasks } className="icon"/>
</div>
</Link>
<Link to={'/users'} className="nav-link" id="usersLink">
<div className="tableElement" id="user">
<FontAwesomeIcon icon={ faUsers } className="icon"/>
</div>
</Link>
I believed that <Link> tags should be wrapped by <Router> tags to work. So if you have the same issue, just check if you wrapped your <Link> tags by <Router> tags, and delete them.

Trying to load child component in react router v4 in switch tag

I am trying to load child component in react router, but in parent component it gives an error of props undefined.
//Here's my app.js file where child component is loaded.
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
return (
<Provider store={store}>
<div className="App">
<Navbar>
<Router>
<Switch>
<Route exact path="/" component={Landing} />
</Switch>
</Router>
</Navbar>
</div>
</provider>
//Heres my code for navbar component.
const Navbar = ({ props, auth }) => ({
render() {
const authLinks = (
<ul className="nav navbar-nav">
<li className="current">Auth Home</li>
<li>About</li>
<li>Service</li>
<li>Works</li>
<li>Team</li>
<li>Contact</li>
</ul>
);
const guestLinks = (
<ul className="nav navbar-nav">
<li className="current"><Link to="/">Guest Home</Link></li>
<li>About</li>
<li>Service</li>
<li>Works</li>
<li>Team</li>
<li>Contact</li>
</ul>
);
return (
<Fragment>
<nav className="navbar navbar-default" role="navigation">
<div className="container">
<div className="navbar-header">
<button type="button" className="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span className="sr-only">Toggle nav</span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
<Link className="navbar-brand" to="/">VDOXON</Link>
</div>
<div className="navigation collapse navbar-collapse navbar-ex1-collapse">
{auth.isAuthenticated ? (authLinks) : (guestLinks)}
</div>
</div>
</nav>
<div className='container'>
{props.children}
</div>
</Fragment>
)
}
})
//Can anyone tell me the exact the way to load the child component into a main component while routing in react.

Why is this code giving a warning about functions not being valid as a React child?

The warning is: Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
render() {
return (
<div className="App">
<AppContext.Provider value={this.state}>
<Navbar> <!-- this is the line React gives warning about -->
<Route exact path="/">
Welcome to the Library Management System
</Route>
<Route exact path="/about">
The About Page
</Route>
<Route exact path="/new-books">
<NewBooks />
</Route>
<Route exact path="/my-account">
<MyAccount />
</Route>
</Navbar>
</AppContext.Provider>
</div>
);
}
This is what I have in my Navbar.js file:
import React from 'react';
import { BrowserRouter as Router, Switch, Link } from 'react-router-dom';
import './Navbar.css';
import AppContext from "../AppContext";
class UserLoggedInMenu extends React.Component {
render() {
return (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link to="/my-account" className="nav-link">
My Account
</Link>
</li>
<li className="nav-item">
<Link to="/logout" className="nav-link">
Log Out
</Link>
</li>
</ul>
)
}
};
class UserLoggedOutMenu extends React.Component {
render() {
return (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link to="/my-account" className="nav-link">
Log In
</Link>
</li>
</ul>
)
}
};
export default class Navbar extends React.Component {
render() {
return (
<div id="Navbar">
<AppContext.Provider>
{(context) => (
<Router>
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container">
<Link to="/" className="navbar-brand">
Library Management System
</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<Link to="/new-books" className="nav-link">
New Books
</Link>
</li>
</ul>
{context.userLoggedIn ? <UserLoggedInMenu /> : <UserLoggedOutMenu />}
</div>
</div>
</nav>
<main className="container">
<Switch>
{this.props.children}
</Switch>
</main>
</Router>
)}
</AppContext.Provider>
</div>
);
}
}
It seems as though React thinks that <Navbar> was defined as a function, but clearly it isn't.
Providers don't take functions as children:
<AppContext.Provider>
{(context) => (
You want a consumer:
<AppContext.Consumer>
{(context) => (
In the future, an easy way to debug this is to start removing components until you find the one causing the error.

Home Page overlaps with other page even if we use exact with Using React Route

I am trying to route to new component upload.js .I am using react and exact for hiding other component in home page.When I click Upload.it shoud redirect to UploadFileComponent component .what is happening is UploadFileComponent is loading and overlapping with all other component .added exact with but its not working
//app.js
function Appp() {
return (
<div className="App">
<HeaderComponent></HeaderComponent>
<Router>
<Route exact path="/" component={HomeComponent}></Route>
</Router>
</div>
);
}
//home.js(conatinerComponent)
class HomeComponet extends Component {
construct(props) { }
render() {
return (
<div className="App">
<div className="container">
<div className="App-body">
<SideBarComponent></SideBarComponent>
<ArticleComponent></ArticleComponent>
</div>
</div>
<FooterComponent></FooterComponent>
</div>
)
}
}
//header.js
class HeaderComponent extends Component {
render() {
return (
<Router>
<div className="header">
<div className="container">
<div className="header-content">
<img src={logo} alt="logo"></img>
<div className="nav-links" >
<ul >
<li>Home</li>
<li>About</li>
<li>Services</li>
<li><NavLink activeClassName="active" to="/upload" >Upload</NavLink></li>
{/* <li><Link to="/upload">Upload</Link></li> */}
</ul>
</div>
</div>
</div>
</div>
<Route path="/upload" exact component={UploadFileComponent} />
</Router>
);
}
}
your links and all route should be in single <Router></Router>. Please don't use it multiple times.
Can you please try this...
function Appp() {
return (
<Router>
<div className="App">
<HeaderComponent />
<Route path="/" exact component={HeroImageComponent} />
<div className="container">
<div className="App-body">
<Route exact path="/" component={SideBarComponent} />
<Route path="/" exact component={ArticleComponent} />
<Route path="/upload" exact component={UploadFileComponent} />
</div>
</div>
<Route path="/" exact component={FooterComponent} />
</div>
</Router>
);
}
class HeaderComponent extends Component {
render() {
return (
<div className="header">
<div className="container">
<div className="header-content">
<img src={logo} alt="logo" />
<div className="nav-links">
<ul>
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>
<Link to="/upload">Upload</Link>
</li>
</ul>
</div>
</div>
</div>
</div>
);
}
}
According to docs:
The <Switch> is not required for grouping <Route>s, but it can be quite useful. A <Switch> will iterate over all of its children <Route> elements and only render the first one that matches the current location. This helps when multiple route’s paths match the same path-name, when animating transitions between routes, and in identifying when no routes match the current location (so that you can render a “404” component).
You need to add a <switch>your routes here</switch> to render exact one component.
Note :: Also in your code snippet, you are using same path for all the routes. You need to change the path for each component otherwise for every path only first component will get render.
UPDATE
Suppose you have more than 1 components to show on single route then create a container component and import all the other components to that container component like,
import React from 'react';
import HeroImageComponent from './HeroImageComponent';
import SideBarComponent from './SideBarComponent';
import ArticleComponent from './ArticleComponent';
import FooterComponent from './FooterComponent';
class ContainerComponent extends React.Component{
render(){
return(
<div>
<HeroImageComponent />
<SideBarComponent />
<ArticleComponent />
<FooterComponent />
</div>
)
}
}
export default ContainerComponent;
Then your route will be,
function App() {
return (
<div className="App">
<HeaderComponent></HeaderComponent> //This can be added to HomeComponent
<Router>
<Route exact path="/" component={HomeComponent}></Route>
<Route path="/upload" exact component={UploadFileComponent} />
</Router>
</div>
);
}
Your header component should be,
class HeaderComponent extends Component {
render() {
return (
<Router>
<div className="header">
<div className="container">
<div className="header-content">
<img src={logo} alt="logo"></img>
<div className="nav-links" >
<ul >
<li>Home</li>
<li>About</li>
<li>Services</li>
<li><NavLink activeClassName="active" to="/upload" >Upload</NavLink></li>
{/* <li><Link to="/upload">Upload</Link></li> */}
</ul>
</div>
</div>
</div>
</div>
</Router>
);
}
}

React router doesnt route when clicking on link

so i have a header component with a couple of links:
{
this.props.cats.map(x =>
<li className="nav-item" key={x.path}><Link className="nav-link" to={x.path}>{x.name}</Link></li>)
}
The code snippet above is what i use to render the links
Then in my index.js(root) i use <BrowserRouter/> and it encompasses the whole element.
My question is to do with the routing i have implemented.
<Header />
<Switch>
<Route exact path='/' component={(props) => <PostList cat='all' posts={this.props.posts} />} />
<Route exact path='/:category' component={(props) => {
console.log(props.match.url)
return <PostList cat='filter' posts={this.props} />
}} />
</Switch>
When i click on the link to take me to say path "/test" it should be picked up by the second Route element and every time it changes it should display the link, it doesn't. It will only change if i do a hard refresh.
Any idea on what i could be doing wrong?
Edit* included header component
<nav className="navbar navbar-expand-sm navbar-light bg-light mb-3">
<div className="container">
<Link className="navbar-brand" to='/'>Navbar</Link>
<button className="navbar-toggler" data-toggle="collapse" data-target="#navbarNav"><span className="navbar-toggler-icon"></span></button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="ml-auto navbar-nav">
{
this.props.cats.map(x =>
<li className="nav-item" key={x.path}><Link className="nav-link" to={x.path}>{x.name}</Link></li>)
}
</ul>
</div>
</div>
</nav>
Link is now part of 'react-router-dom', make sure you have imported it from there ,if this doesn't solve your problem then try to wrap your component with withRouter

Resources