navbar re rendered when state changed - javascript

I'm fairly new to react and JSX, and looking for some help!
I have part of my app that pulls state from redux to show if a user is logged in, and I just want to render the navbar component because some things are behind protected routes. Everything is working how I want it to, except that I have to refresh the page to make the changes happen, so I'm looking to just have it update based on the state passed to it when it changes OR could be part of an onclick event in the logout component
Here's the navbar component
export default class Navbar extends Component {
render() {
const storeAuth = store.getState();
const isLoggedIn = (storeAuth['auth']['isAuthenticated'])
if(isLoggedIn){
return (
<nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/login" className="navbar-brand">CHK List</Link>
<div className="collpase navbar-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/list" className="nav-link">Daily Checklist </Link>
</li>
<li className="navbar-item">
<Link to="/editlist" className="nav-link">Edit Checklist</Link>
</li>
<li className="navbar-item">
<Link to="/Register" className="nav-link">Register New Users</Link>
</li>
<li className="navbar-item">
<Link to="/Logout" className="nav-link">Logout</Link>
</li>
</ul>
</div>
</nav>
);
}else{
return (
<nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/dashboard" className="navbar-brand">CHK List</Link>
<div className="collpase navbar-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/login" className="nav-link">Login</Link>
</li>
</ul>
</div>
</nav>
);
}
}
}
And this is the Logout component where the onclick event
class Dashboard extends Component {
onLogoutClick = e => {
e.preventDefault();
this.props.logoutUser();
};
render() {
const { user } = this.props.auth;
return (
<div style={{ height: "75vh" }} className="container valign-wrapper">
<div className="row">
<div className="landing-copy col s12 center-align">
<h4>
<b>Hey {user.name.split(" ")[0]}</b> <p></p>
<p className="flow-text grey-text text-darken-1">
Are you sure you want to logout?
</p>
</h4>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
onClick={this.onLogoutClick}
className="btn btn-large waves-effect waves-light hoverable blue accent-3">
Logout
</button>
</div>
</div>
</div>
);
}
}
Dashboard.propTypes = {
logoutUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired
};

You can try using mapStateToProps function.
import {connect} from 'react-redux';
class Navbar extends Component {
render() {
let isLoggedIn = this.props.isLoggedIn
if(isLoggedIn){
return (
<nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/login" className="navbar-brand">CHK List</Link>
<div className="collpase navbar-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/list" className="nav-link">Daily Checklist </Link>
</li>
<li className="navbar-item">
<Link to="/editlist" className="nav-link">Edit Checklist</Link>
</li>
<li className="navbar-item">
<Link to="/Register" className="nav-link">Register New Users</Link>
</li>
<li className="navbar-item">
<Link to="/Logout" className="nav-link">Logout</Link>
</li>
</ul>
</div>
</nav>
);
}else{
return (
<nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/dashboard" className="navbar-brand">CHK List</Link>
<div className="collpase navbar-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/login" className="nav-link">Login</Link>
</li>
</ul>
</div>
</nav>
);
}
}
}
const mapStateToProps=(state)=>{
return {
isLoggedIn : state.auth.isAuthenticated
}
}
export default connect(mapStateToProps)(Navbar )

Related

Create navbar for login page

import React from "react";
import { Link } from "react";
function Navbar() {
return <nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/" className="navbar-brand">React Routing Example</Link>
<div className="ml-auto">
<ul className="navbar-nav">
<li className="nav-list"><Link className="nav-link" to="/home">Home</Link></li>
<li className="nav-list"><Link className="nav-link" to="/about">About</Link></li>
<li className="nav-list"><Link className="nav-link" to="/service">Services</Link></li>
<li className="nav-list"><Link className="nav-link" to="/contact">Contact</Link></li>
</ul>
</div>
</nav>
}
export default Navbar;
then not showing navbar in browser showing error
react-jsx-dev-runtime.development.js:87
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
creating Navabar for lofin form
You need to import Link from react-router-dom.
import React from "react";
import { Link } from "react-router-dom";
function Navbar() {
return <nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/" className="navbar-brand">React Routing Example</Link>
<div className="ml-auto">
<ul className="navbar-nav">
<li className="nav-list"><Link className="nav-link" to="/home">Home</Link></li>
<li className="nav-list"><Link className="nav-link" to="/about">About</Link></li>
<li className="nav-list"><Link className="nav-link" to="/service">Services</Link></li>
<li className="nav-list"><Link className="nav-link" to="/contact">Contact</Link></li>
</ul>
</div>
</nav>
}
export default Navbar;
You import Link from react that doesn't exist in react
you should use react-router for to use 'Link'.
You should import { Link } from "react-router-dom", instead of importing it from "react" as it doestn't exist in "react". You can read more about the "react-router-dom" here https://reactrouter.com/en/main
import React from "react";
import { Link } from 'react-router-dom'
function Navbar() {
return <nav className="navbar navbar-dark bg-dark navbar-expand-lg">
<Link to="/" className="navbar-brand">React Routing Example</Link>
<div className="ml-auto">
<ul className="navbar-nav">
<li className="nav-list"><Link className="nav-link" to="/home">Home</Link></li>
<li className="nav-list"><Link className="nav-link" to="/about">About</Link></li>
<li className="nav-list"><Link className="nav-link" to="/service">Services</Link></li>
<li className="nav-list"><Link className="nav-link" to="/contact">Contact</Link></li>
</ul>
</div>
</nav>
}
export default Navbar;

Buttons on Navbar not aligned in reactJS

I am using the navbar from bootstrap 5. I having an UI issue.
What do I have?
This is the navbar I am currently having.
What do I want?
I want to align the navbar buttons (Login and Signup) to the right end.
import React from "react";
import { Link, useNavigate } from "react-router-dom";
const Navbar = (props) => {
let navigate = useNavigate();
const handleLogout = () => {
localStorage.removeItem("token");
console.log("hello");
navigate("/login");
props.showAlert("User Logged Out succesfully! ", "info");
};
return (
<>
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<Link className="navbar-brand" to="/">
Navbar
</Link>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav">
<li className="nav-item">
<Link className="nav-link active" aria-current="page" to="/">
Home
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/about">
About
</Link>
</li>
</ul>
{!localStorage.getItem("token") ? (
<form className="d-flex">
<Link
className="btn btn-outline-success mx-2"
to="/signup"
role="button"
>
SignUp
</Link>
<Link
className="btn btn-outline-success"
to="/login"
role="button"
>
Login
</Link>
</form>
) : (
<form className="d-flex">
<button
className="btn btn-outline-success mx-2"
onClick={handleLogout}
>
LogOut
</button>
</form>
)}
</div>
</div>
</nav>
</>
);
};
export default Navbar;
I have tried many attempts but still, it is not working. I am using bootstrap built-in classes also.
You just need to add a me-auto class with <ul> as given <ul class="navbar-nav me-auto">
import React from "react";
import { Link, useNavigate } from "react-router-dom";
const Navbar = (props) => {
let navigate = useNavigate();
const handleLogout = () => {
localStorage.removeItem("token");
console.log("hello");
navigate("/login");
props.showAlert("User Logged Out succesfully! ", "info");
};
return (
<>
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<Link className="navbar-brand" to="/">
Navbar
</Link>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li className="nav-item">
<Link className="nav-link active" aria-current="page" to="/">
Home
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/about">
About
</Link>
</li>
</ul>
{!localStorage.getItem("token") ? (
<form className="d-flex">
<Link
className="btn btn-outline-success mx-2"
to="/signup"
role="button"
>
SignUp
</Link>
<Link
className="btn btn-outline-success"
to="/login"
role="button"
>
Login
</Link>
</form>
) : (
<form className="d-flex">
<button
className="btn btn-outline-success mx-2"
onClick={handleLogout}
>
LogOut
</button>
</form>
)}
</div>
</div>
</nav>
</>
);
};
export default Navbar;
Just need to add me-auto in <ul> like this:
<ul className="navbar-nav me-auto">

Bootstrap Mobile-Navbar not collapsed

In the mobile Version the navbar is not collapsing... Can somebody help. Does anybody see my mistake?I copy the source from bootstrap but it didn't work. it does not work because I work with react?
I would be grateful for any help
file App.js
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
//Partikeln importieren
import Particles from 'react-particles-js';
//Hier importiert man seine Komponenten
import Navbar from "./components/Navbar";
import Header from "./components/Header";
...
...
...
file Navbar code
import React from 'react'
import Logo from "../img/logo_large.png"
// React Font awesome imports
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faBars } from "#fortawesome/free-solid-svg-icons"
//React-scroll install
//Navbar
const Navbar = () => {
return (
<nav className="navbar navbar-expand-lg navbar-light bg-dark fixed-top">
<div className="container">
{/*Logo variable von oben*/}
<a className="navbar-brand" href="#home"><img className="Logo" src={Logo} /> </a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<FontAwesomeIcon icon={faBars} style={{ color: "#fff" }} />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav ml-auto">
<li className="nav-item active">
<a className="nav-link" href="#about" >About Me<span className="sr-only">(current)</span></a>
</li>
<li className="nav-item">
<a className="nav-link" href="#services">Services</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#experiences">Experiences</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#abilities">Abilities</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#blog">Blog</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#freetime">Freetime</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#contact">Contact</a>
</li>
</ul>
</div>
</div>
</nav >
)
}
export default Navbar
Remove the div element with the container name.

React.js Navbar Hamburger Menu won't toggle closed

So, I have a react.js app built with a group. Our Navbar works, but when the Navbar is toggled from a smaller screen using the Hamburger menu, it will open, but the toggle doesn't work to close it, it stays stuck open. I didn't program this page, but I've been trying to debug why it won't close, and for what I can see, it should work.
Yes, I know react.bootstrap is a thing, and I was thinking about converting it, but I'm on a deadline and don't want to rewrite this entire component from scratch if it is at all possible. Any thoughts, or suggestions. I thought it was likely in the toggleNav function, but from what I've tested it seems to be correct.
import React, { Component } from "react";
import { Link } from "react-router-dom";
import "./style.css";
class Nav extends Component {
state = {
open: false,
width: window.innerWidth,
};
updateWidth = () => {
const newState = { width: window.innerWidth };
if (this.state.open && newState.width > 991) {
newState.open = false;
}
this.setState(newState);
};
toggleNav = () => {
this.setState({ open: !this.state.open });
};
setActiveNavItem = (path) => {
return window.location.pathname === path ? "nav-link active" : "nav-link";
};
componentDidMount() {
window.addEventListener("resize", this.updateWidth);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWidth);
}
render() {
return (
<nav className="navbar navbar-expand-lg navbar-light">
<Link className="navbar-brand" to="/">
Seenit
</Link>
<button
onClick={this.toggleNav}
className="navbar-toggler"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div
className={`${this.state.open ? "" : "collapse "}navbar-collapse`}
id="navbarNav"
>
{/* Navbar items */}
<ul className="navbar-nav">
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/")}
to="/"
>
Home
</Link>
</li>
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/create-post")}
to="/create-post"
>
Create a Post
</Link>
</li>
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/log-in")}
to="/log-in"
>
Log In
</Link>
</li>
<li className="nav-item">
<Link
onClick={this.toggleNav}
className={this.setActiveNavItem("/sign-up")}
to="/sign-up"
>
Sign Up
</Link>
</li>
</ul>
</div>
</nav>
);
}
}
export default Nav;
This React component is a direct implementation of the Bootstrap Toggler Navbar.
Unfortunately, this component also contains code that modifies the navbar, which almost certainly breaks the Bootstrap code that controls collapsible navbars.
Here is the pure HTML version of this navbar component. Note that it collapses to a hamburger on narrow screens (as desired).
It should be straightforward to remove from this component the code that modifies the Bootstrap Toggler navbar.
.navbar {
outline: 1px solid #ddd;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<body class="p-2">
<nav class="navbar navbar-expand-lg navbar-light mr-5">
<a class="navbar-brand" href="#">Seenit</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Create a Post</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Log In</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Sign Up</a>
</li>
</ul>
</div>
</nav>
<!-- JS required for Bootstrap -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>

Show LoggedIn username on successful login [getting JSX and Router related error in code] --

My aim is to show logged in user name and a logout link in the header section.
User logs in to my app. with username and password. Upon successful login,
I would like to show the respective username in the top right header strip, along with a logout link.
header strip html [located in App.js] -
<nav className="navbar navbar-expand-lg navbar-light bg-custom">
<a className="navbar-brand" href="https://www.sellcodes.com/pro_indigo" target="_blank">
<img src={logoMain} width="30" height="30" alt="" />
</a>
<Link to="/" className="navbar-brand">Football Legends</Link>
<div className="collpase nav-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/" className="nav-link">Players</Link>
</li>
<li className="navbar-item">
<Link to="/create" className="nav-link">Create Player</Link>
</li>
<li className="navbar-item">
<Link to="/hallofFamers" className="nav-link">Hall of Fame</Link>
</li>
<li className="navbar-item" style={{marginLeft:680}}>
<Link to="/login" className="nav-link">Login</Link>
</li>
<li className="navbar-item" style={{ marginLeft: 12 }}>
<Link to="/register" className="nav-link">Sign Up</Link>
</li>
</ul>
</div>
</nav>
login.js code -
import { login } from './shared/UserFunction';
onSubmit(e) {
e.preventDefault()
const user = {
email: this.state.email,
password: this.state.password
}
login(user).then(res => {
this.props.history.push(`user/dashboard`)
})
}
As you can understand I have a separate file where my login implementation logic is written and I have just imported from there.
UserFunction.js code -
import axios from 'axios';
import { Router, Route, Link, RouteHandler } from 'react-router';
export const login = user => {
return axios
.post('http://localhost:4000/users/login', {
email: user.email,
password: user.password
})
.then(response => {
localStorage.setItem('usertoken', (response.data));
console.log('Login Successful');
return response.data
})
.catch(err => {
console.log(err)
})
}
export const findToken = () => {
return localStorage.getItem('usertoken');
}
export const logout =()=>
{
localStorage.removeItem('usertoken');
this.props.history.push('/login');
}
What I how I tried to do this is by following much the same approach in Angular *ngIf and templates.
So I tried following code -
import { findToken } from './components/shared/UserFunction';
<nav className="navbar navbar-expand-lg navbar-light bg-custom">
<a className="navbar-brand" href="https://www.sellcodes.com/pro_indigo" target="_blank">
<img src={logoMain} width="30" height="30" alt="" />
</a>
<Link to="/" className="navbar-brand">Football Legends</Link>
<div className="collpase nav-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/" className="nav-link">Players</Link>
</li>
<li className="navbar-item">
<Link to="/create" className="nav-link">Create Player</Link>
</li>
<li className="navbar-item">
<Link to="/hallofFamers" className="nav-link">Hall of Fame</Link>
</li>
{findToken &&
[
<li className="navbar-item" style={{marginLeft:680}}>
<Link to="/user/profile" className="nav-link">{the username supposed to be here}</Link>
</li>
<li className="navbar-item" style={{ marginLeft: 12 }}>
<Link to="/login" className="nav-link">Logout</Link>
</li>
]
}
<li className="navbar-item" style={{marginLeft:680}}>
<Link to="/login" className="nav-link">Login</Link>
</li>
<li className="navbar-item" style={{ marginLeft: 12 }}>
<Link to="/register" className="nav-link">Sign Up</Link>
</li>
</ul>
</div>
</nav>
But this is giving me a host of errors related to JSX and Parent Element Router.
So how should I approach this? A better way/technique that I can follow? I tried the above after consulting some other links. What is the best way to do this in my scenario?
EDITS: I did some modification on my code but still not getting my desired outcome.
<nav className="navbar navbar-expand-lg navbar-light bg-custom">
<a className="navbar-brand" href="https://www.sellcodes.com/pro_indigo" target="_blank">
<img src={logoMain} width="30" height="30" alt="" />
</a>
<Link to="/" className="navbar-brand">Football Legends</Link>
<div className="collpase nav-collapse">
<ul className="navbar-nav mr-auto">
<li className="navbar-item">
<Link to="/" className="nav-link">Players</Link>
</li>
<li className="navbar-item">
<Link to="/create" className="nav-link">Create Player</Link>
</li>
<li className="navbar-item">
<Link to="/hallofFamers" className="nav-link">Hall of Fame</Link>
</li>
{localStorage.getItem('usertoken')!==null ?
<React.Fragment>
<li className="nav-item" style={{ marginLeft: 680 }}>
<Link to="/profile" className="nav-link">
User
</Link>
</li>
<li className="nav-item" style={{ marginLeft: 12 }}>
<a href="" onClick={this.logOut.bind(this)} className="nav-link">
Logout
</a>
</li>
</React.Fragment>
:
<React.Fragment>
<li className="navbar-item" style={{ marginLeft: 680 }}>
<Link to="/login" className="nav-link">Login</Link>
</li>
<li className="navbar-item" style={{ marginLeft: 12 }}>
<Link to="/register" className="nav-link">Sign Up</Link>
</li>
</React.Fragment>
}
</ul>
</div>
</nav>
As you can see, I added a ternary expression checking the availability of the storage token and then, based on that, 2 React Fragments to show different links. I am still not getting it however.
Upon login, it shows the same Login and SignUp links.
Can you tell me why? What's the error? What's the reason neither of the above 2 approaches worked? Can anyone spot it?

Categories