Problem with responsive nav menu in React - reactjs

I have a problem with a navigation responsive menu.
When I resize the page, I can see the hamburger menu and everything works fine.But I am trying to put a toggle or slidetoggle in react like in jquery.I created a toggle button but does not work correctly. Above is the code, I created a handleClick button for the hamburger menu and a state cond. className="mynav" in css file is display:none;. I want when the size of page is small and when I push the hamburger button to see the menu.
import React, { Component } from 'react'
import './Navbar.css';
import {Link} from 'react-router-dom';
export default class Navbar extends Component {
state = {
cond: false,
}
handleClick=()=>{
this.setState({
cond:!this.state.cond
})
}
render() {
return (
<nav>
<div className="mylogo">
<div className="logo">
logo
</div>
<div id="mybtn" onClick={this.handleClick}>
<div className="bar1"></div>
<div className="bar2"></div>
<div className="bar3"></div>
</div>
</div>
{this.state.cond ? <div className="mynav" >
<ul>
<li>
<Link to='/'>home</Link>
</li>
<li>
<Link to='/about'>About</Link>
</li>
<li>
<Link to='/projects'>Projects</Link>
</li>
<li>
<Link to='/contact'>Contact</Link>
</li>
</ul>
</div> :false
}
</nav>
)
}
}

Wrap you state declaration in a constructor, something like this:
export default class Navbar extends Component {
constructor(props) {
super(props)
this.state = {
cond: false,
};
}
Then your onClick method will have access to the keyword 'this'. It wasn't able to access this.state without that.

Related

change display property in a component from another in React

i'm an beginner in react i try to make a website with it
my problem is change a CSS property for a component from another one to open a Nav menu
i make that with querySelector but i don't know if that is the best way to do
here to open the nav menu :
import './Navbar.css'
function Navbar() {
const handOpenMenu = () => {
const navMenu = document.querySelector(".navMenu");
navMenu.style.cssText = 'display: flex'
}
return (
<header className="navbar container">
<a className='logo' href='/#'>pure mix</a>
<i className="fa-solid fa-bars burgerBtn" onClick={handOpenMenu}></i>
</header>
)
}
export default Navbar
and here for close the nav menu :
import "./Navmenu.css";
function Navmenu() {
const handlCloseMenu = () => {
const navMenu = document.querySelector(".navMenu");
navMenu.style.cssText = "display: none";
}
return (
<div className="navMenu">
<a className="navItem" href="/#">
home
</a>
<a className="navItem" href="/#">
about
</a>
<a className="navItem" href="/#">
logo
</a>
<a className="navItem" href="/#">
contact
</a>
<i className="fa-solid fa-xmark close" onClick={handlCloseMenu}></i>
</div>
);
}
export default Navmenu;
Using useState hook for change state in your component
The best solution would be to use the useState hook and pass in Boolean values of true or false. True would render the navbar component while false would not render it. Here is a link that describes how you would implement this in the best way possible(https://blog.logrocket.com/how-create-multilevel-dropdown-menu-react/)

Is there a way to add the Auth0 sign in button to the navbar using some Javascript

I am trying to add the Auth0 button to a navbar but the jsx linter does not like it when I add javascript. I need the conditional so it shows up for non registered users. I have tried importing it from another component ion React as well as adding it directly in the jsx with no luck. I keep getting isAuthenticated' is not defined and loginWithRedirect' is not defined. Not sure what to do next. Thanks.
import $ from 'jquery'
import '../styles/nav.scss'
import button from '../components/GoogleButton/Button.jsx'
import { auth0 } from './auth0/react-auth0-spa'
export default class NavBar extends Component {
componentDidMount() {
$(document).ready(function() {
$('.mobile-button a').click(function(e) {
$(this)
.parent()
.parent()
.toggleClass('open')
$(this).html($(this).html() === 'Close Menu' ? 'Menu' : 'Close Menu')
e.preventDefault()
})
})
}
render() {
return (
<div>
<header class='header'>
<div class='container'>
<h1 class='site-title'>Super Cool Web App!</h1>
<span class='site-tagline'>Because Andy made this!</span>
</div>
</header>
<nav class='main-nav'>
<div class='container'>
<ul>
<li class='mobile-button'>
<a href='/'>Menu</a>
</li>
<li>
<a href='/'>About</a>
</li>
<li>
{/* this is where the problem lies */}
{!isAuthenticated && (
<button onClick={() => loginWithRedirect({})}>Log in</button>
)}
</li>
<li>
<a href='/'>Methods</a>
</li>
<li>
<a href='/'>Results</a>
</li>
<li>
<a href='/'>Contact</a>
</li>
<li>
<a href='/'>Methods</a>
</li>
<li>
<a href='/'>Results</a>
</li>
<li>
<a href='/'>Contact</a>
</li>
</ul>
</div>
</nav>
</div>
)
}
}```
authO is for initializing you need to use useAuthO to access the api elsewhere in your project.
Change your import statement to:
import { useAuth0 } from "../react-auth0-spa";
Then deconstruct AuthO methods isAuthenticated and loginWithRedirect.
Right under render and before your return put:
const {isAuthenticated , loginWithRedirect} = useAuth0
https://auth0.com/docs/quickstart/spa/react#create-the-navbar-component

react-scroll target element not found

I have a Navbar React component with a Link component which needs to scroll down to Section component when clicked. I have implemented react-scroll, however, when I click on the Link component, I get target element not found in the browser console.
The Navbar component:
import React, { Component } from "react";
import { Link, animateScroll as scroll, scroller } from "react-scroll";
class Navbar extends Component {
render() {
return (
<div>
<ul>
<li>
<Link to="section1" activeClass="active" spy={true} smooth={true}>
Section 1
</Link>
</li>
</ul>
</div>
);
}
}
export default Navbar;
And the App.js file:
import React from "react";
// Styling
import "./styles/App.css";
// Components
import Navbar from "./components/Navbar";
import SectionOne from "./components/SectionOne";
function App() {
return (
<div className="App">
<div>
<Navbar />
<SectionOne id="section1"/>
</div>
</div>
);
}
export default App;
I used this repo as a reference, however, things don't work. What have I missed here?
I have implemented a div inside of the SectionOne component
<div id="section-one-wrapper">Section One content...</div>
and then specified that id in the Link component:
<Link to="section-one-wrapper" activeClass="active" spy={true} smooth={true}>
Section 1
</Link>
and it worked.

Trying to use Bootstrap Nav Pills in React Router's NavLink

I am having trouble using the default Bootstrap Nav pills as the links on the Navbar for my page, where they show if the pill is active or not. As I have the code, the NavLink is just in plain text and I can't seem to use any of the active styling from Bootstrap.
I am using Bootstrap 4 and React with React Router.
import React, { Component } from "react";
import { NavLink } from "react-router-dom";
class NavBar extends Component {
render() {
return (
<nav className="navbar navbar-expand-lg bg-light navbar-light">
<ul className="nav nav-pills">{this.renderNavLinks()}</ul>
</nav>
);
}
renderNavLinks() {
const navButton = {
padding: "10px"
};
return this.props.navLinks.map(l => (
<li className="nav-item" style={navButton}>
<NavLink className="active" to={"/" + l.id}>{l.text}</NavLink>
</li>
));
}
}
export default NavBar;
I want my NavBar to actively show what page is currently being displayed using Bootstrap's default pill style buttons.
You are missing the nav-link css class on the NavLink component.
<NavLink className="nav-link" to={"/" + l.id}>{l.text}</NavLink>
Reference

height control of the element with React

Just started with the react and some simple things can get hard after years of jQuery
I want to render list of books and since the description is too long to display I want to limit the height of the div. onClick I want to display full description text and close it if clicked again.
like so: https://jsfiddle.net/nb1u1f9t/
Here is my function that renders books list:
renderBooks(){
return(
<div>
<h3>List of available books</h3>
<ul className="list-group">
{this.props.books.map((book)=>{
return (
<li key={book.id} className="list-group-item">
<div className="cover-img"><img src={book.cover_img} alt="" className="img-responsive" /></div>
<div className="book-info">
<ul className="list-group">
<li className="list-group-item active"><h4>Name: {book.name} </h4></li>
<li className="list-group-item">Pages: {book.pages_i}</li>
<li className="list-group-item">Genre: {book.genre_s}</li>
<li className="list-group-item">Price: {book.price}</li>
<li className="list-group-item">Description: <div className="description-frame">{renderHTML(book.description)}</div><div className="view-all" onClick={}>View All</div></li>
</ul>
</div>
</li>
);
})}
</ul>
</div>
);
I would appreciate the general idea how that can be accomplished in React style? I feel there should be something related to the state but cannot think of how to do that correctly. Plus not sure how the context for the specific book should be handled through the click event.
I would have two react components, BookList and Book.
Book would have a boolean value on its state to indicate whether it was expanded or not. It would also have an onClick handler which toggles the expanded state by calling this.setState({ expanded: !this.state.expanded })
Then it would just be up to book's render function to look at the state, and apply an additional CSS class for the case the book is not expanded, as per Kenneth's comment.
Adding a code in case somebody need the same solution
That is how my new code looks like:
component that renders books list:
import React, {Component} from 'react';
import BookDescription from './description_render';
export default class RenderBooks extends Component{
constructor(props){
super(props);
}
render(){
return(
<div>
<h3>List of available books</h3>
<ul className="list-group">
{this.props.books.map((book)=>{
return (
<li key={book.id} className="list-group-item">
<div className="cover-img"><img src={book.cover_img} alt="" className="img-responsive" /></div>
<div className="book-info">
<ul className="list-group">
<li className="list-group-item active"><h4>Name: {book.name} </h4></li>
<li className="list-group-item">Pages: {book.pages_i}</li>
<li className="list-group-item">Genre: {book.genre_s}</li>
<li className="list-group-item">Price: {book.price}</li>
<li className="list-group-item"><BookDescription description={book.description}></BookDescription></li>
</ul>
</div>
</li>
);
})}
</ul>
</div>
);
}
}
New component that holds state for the clicked book description
import React, {Component} from 'react';
import renderHTML from 'react-render-html';
export default class BookDescription extends Component{
constructor(props){
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleViewClick = this.handleViewClick.bind(this);
}
handleViewClick(){
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render(){
return(
<div>
Description: <div className={this.state.isToggleOn ? 'description-frame closed' : 'description-frame'}>{renderHTML(this.props.description)}</div><div className="view-all" onClick={this.handleViewClick}>{this.state.isToggleOn ? 'View All' : 'Close'}</div>
</div>
)
}
}

Resources