On the small screen, it doesn't show/hide. How can I change this code to work on the small screen?
import React from 'react';
import assets from './assets';
import { FaBars, FaFacebook, FaRegHeart, FaInstagram, FaLinkedin, FaStar, FaStarHalf, FaTimes, FaTwitter } from 'react-icons/fa';
var navLinks = document.getElementById('navLinks');
function showMenu() {
navLinks.style.right = "0";
}
function hideMenu() {
navLinks.style.right = "-200px";
}
Above var worked a few times mistakenly, but I still did not get it.
export const Home = () => (
<>
<section class="header">
<nav>
<img src={assets.logo} alt='Logo' width='100%' />
<div id='navLinks' class='nav-links'>
<FaTimes class='fa' onClick={showMenu} />
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>COURSE</li>
<li>BLOG</li>
<li>CONTACT</li>
</ul>
</div>
<FaBars class='fa' onClick={hideMenu} />
</nav>
<div class="text-box">
<h1>World's Biggest University</h1>
<p>Making website is now one of the easiest thing in the world. You just need to learn HTML, CSS,<br />Javascript and you are good to go.</p>
Visit Us to Know More
</div>
</section>
</>
)
My CSS file is below.
I've tried many ways but I couldn't.
nav .fa{
display: none;
}
As some people have mentioned before you are not utilising the React library correctly.
The (untested) code below should suit you better. As you can see a state has been used instead of directly changing style properties. I have tried to comment the code as clearly as possible but for more in depth instructions i recommend reading the React docs.
import React, { useState } from 'react';
import assets from './assets';
import { FaBars, FaFacebook, FaRegHeart, FaInstagram, FaLinkedin, FaStar, FaStarHalf, FaTimes, FaTwitter } from 'react-icons/fa';
export const Home = () => {
// Set state value to keep track of menu open or closed status
const [navOpen, setNavOpen] = useState(false)
// Open the active menu
const open = () => {
setNavOpen(true)
}
// Close the active menu
const close = () => {
setNavOpen(false)
}
return (
<>
<section class="header">
<nav>
<img src={assets.logo} alt='Logo' width='100%' />
<div id='navLinks' class='nav-links'>
<button onClick={open}>
<FaTimes class='fa' />
</button>
{
// Only render the UL node when the navOpen variable is true
navOpen && (
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>COURSE</li>
<li>BLOG</li>
<li>CONTACT</li>
</ul>
)
}
</div>
<button onClick={close}>
<FaBars class='fa' />
</button>
</nav>
<div class="text-box">
<h1>World's Biggest University</h1>
<p>Making website is now one of the easiest thing in the world. You just need to learn HTML, CSS,<br />Javascript and you are good to go.</p>
Visit Us to Know More
</div>
</section>
</>
)
}
Related
Guys I need your help with an issue. I am recently learning how to use React. The question is this: I have three h2 elements, each with a different id attribute. What I am trying to do is create a list consisting of as many "a" elements as there are h2 elements. Each "a" element should have the href attribute pointing to the respective h2 element.
I show you what I have tried to do. With the code I wrote the list remains blank.
import logo from './logo.svg';
import './App.css';
import { Link } from "react-router-dom";
function App() {
const h2 = Array.from(document.getElementsByTagName('h2'));
const list = h2.map(element => {
return (
<li key={element.id}>
<Link to={`${element.id}`}>{element.innerHTML}</Link>
</li>
);
})
return (
<div className="App">
<h2 id="first">First item</h2>
<h2 id="second">Second item</h2>
<h2 id="Third">Third item</h2>
<h4>List of h2:</h4>
<ul>
{list}
</ul>
</div>
);
}
export default App;
Could you tell me what I should do or the concepts I should go to study?
There are two problems in above solution.
Fetching H2s before they render for the first render.
Missed appending # before redirection link for ID.
Here's the solution. I have used a tag instead of react-router's Link but it will work in similar pattern.
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const [list, setList] = useState([]);
useEffect(() => {
// Added this in useEffect as we endup fetching h2s before they render if kept outside. Here they will be fetched post first render
const h2 = Array.from(document.getElementsByTagName("h2"));
const currentList = h2.map((element) => {
return (
<li key={element.id}>
<a href={`#${element.id}`}>{element.innerHTML}</a>
</li>
);
});
setList(currentList);
}, []);
return (
<div className="App">
<h2 id="first">First item</h2>
<h2 id="second">Second item</h2>
<h2 id="Third">Third item</h2>
<div style={{ height: "100vh" }}>Some space</div>
<h4>List of h2:</h4>
<ul>{list}</ul>
</div>
);
}
Here's a working example at codesandbox, I have added a large div in the center to make scroll visible. Please scroll down the example.
Using useEffect to store the text of h2's and creating Links from it as as below,
change the li to Links as required
const { useState, useEffect } = React;
function App() {
const [h2Count, setH2Count] = useState([]);
useEffect(() => {
const noOfH2s = [...document.querySelectorAll("h2")];
setH2Count(noOfH2s.map((el) => ({ text: el.innerText, id: el.id })));
}, []);
const list = h2Count.map((element, id) => {
return <li key={id}>{`${element.text}-${element.id}`}</li>;
});
return (
<div className="App">
<h2 id="first">First item</h2>
<h2 id="second">Second item</h2>
<h2 id="Third">Third item</h2>
<h4>List of h2:</h4>
<ul>{list}</ul>
</div>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
Please help, I have been trying to write the following code in react syntax but I don't seem to know how to do that and all search I've made online isn't helping
useEffect(() => {
const menuBtn = document.getElementById('menu-btn');
const menu = document.querySelector('.menu')
menuBtn.addEventListener('click', () =>{
menu.classList.toggle('menu-open')
})
}, []);
useEffect(()=>{
const navbar = document.getElementById('navbar')
const offset = 50
window.addEventListener("scroll", () =>{
if(pageYOffset > offset){
navbar.classList.add('navbar-active')
}else{
navbar.classList.remove('navbar-active')
}
})
}, [])
I want to change it because I keep getting the error below
[webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/kimmoramicky/Desktop/fts_portfolio/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[2].oneOf[7].use[1]!/home/kimmoramicky/Desktop/fts_portfolio/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[2].oneOf[7].use[2]!/home/kimmoramicky/Desktop/fts_portfolio/node_modules/bootstrap/dist/css/bootstrap.min.css': No serializer registered for Warning
while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> Array { 1 items } -> webpack/lib/ModuleWarning -> Warning
but when I comment that part out, I don't get the error. Also, the code doesn't work as expected when the page is loaded again.
Below is the complete code for clearer understanding
import React, {useState, useEffect, useRef} from 'react'
import Link from 'next/link'
import { getPosts, getTags, getCategories } from '../services';
import { useRouter } from 'next/router';
import 'react-ionicons'
import 'react-ionicons'
import { FaFacebookSquare, FaGithubSquare, FaInstagramSquare, FaYoutubeSquare } from 'react-icons/fa'
import {ImMenu} from 'react-icons/im'
import {BiSearchAlt} from 'react-icons/bi'
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import Form from 'react-bootstrap/Form';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import NavDropdown from 'react-bootstrap/NavDropdown';
import { filter } from 'domutils';
const Header = () => {
useEffect(() => {
const menuBtn = document.getElementById('menu-btn');
const menu = document.querySelector('.menu')
menuBtn.addEventListener('click', () =>{
menu.classList.toggle('menu-open')
})
}, []);
useEffect(()=>{
const navbar = document.getElementById('navbar')
const offset = 50
window.addEventListener("scroll", () =>{
if(pageYOffset > offset){
navbar.classList.add('navbar-active')
}else{
navbar.classList.remove('navbar-active')
}
})
}, [])
return (
<div className='header1'>
<video id='headerVideo' loop={true} autoplay="autoplay" muted>
<source src="/vidfy-african-cheerful-young-stylish-man-and-w_1920x1080.mp4" type="video/mp4"></source>
Your browser does not support the video tag.
</video>
<div>
<nav id='navbar'>
<div className="menu">
<div>
<a href="#" className='brand'>Menu</a>
<ul>
<li>Blog</li>
<li>What's New</li>
<li>Categories</li>
</ul>
<ul>
<li>Projects</li>
<li>News</li>
<li>Store</li>
<li>About</li>
<li>Contact</li>
</ul>
<ul className='social-media'>
<li><a href="#">
<FaFacebookSquare />
</a></li>
<li><a href="#">
<FaInstagramSquare />
</a></li>
<li><a href="#">
<FaGithubSquare />
</a></li>
<li><a href="#">
<FaYoutubeSquare />
</a></li>
</ul>
<form action="">
<div className="input-wrap">
<input type="search" placeholder='Search...' />
<button type='submit'>
<BiSearchAlt />
</button>
</div>
</form>
</div>
</div>
<div className="container">
<img src="/logo.png" alt="logo" />
<div className="container-inner">
<ul>
<li>Home</li>
<li>Home</li>
<li>Home</li>
</ul>
<form action="">
<div className="input-wrap">
<input type="search" placeholder='Search...' className='text-is-white' />
<button type='submit'>
<BiSearchAlt />
</button>
</div>
</form>
</div>
<ImMenu className='fa-bars' id='menu-btn' />
</div>
</nav>
</div>
<div className="headText">
<p>Grow your business and ideas with KimmoTech</p>
</div>
</div>
)
}
export default Header
so you have a bunch of stuff you should not do that way:
First:
const menuBtn = document.getElementById('menu-btn');
Should be:
export const Component = () => {
const [menuOpen, setMenuOpen = useState(false)
const handleMenuButtonClick = () => setMenuOpen(!menuOpen)
return (
…
<div className={‘menu ${menuOpen ? ‘menu-open’ : ‘menu-closed’}’}/>
<button onClick={handleMenuButtonClick} />
…
)
Then this:
window.addEventListener("scroll", () =>{
if(pageYOffset > offset){
navbar.classList.add('navbar-active')
}else{
navbar.classList.remove('navbar-active')
}
})
}, [])
This is better to use as hook and when you do that you have two things you should have in mind, first one this should be DEBOUNCED otherwise you’l have quite nasty perf hit, second when you subscribe to event like that you have to also unsubscribe:
cons [scrollActive, setScrollActive] = useState(false)
useEffect(() => {
const scroll = window.addEventListener(‘scroll’, (e) => setScrollActive(e > condition));
return () => winodw.removeEventListener(scroll)
}, [])
…
<navbar classNsme={‘navbar ${scrollActive ? ‘scroll-active’ : ‘’}}/>
They would look more like react then it is right now…
The issue occurred because you used webpack on react app.
It'll be disappeared if you create the app with "create-react-app".
Hope it'll be helpful for you.
I would recommend to switch from useEffect to using useState to manage the state of your components including classes. Also React provides an easy and smooth way to manage your event handlers such as onClick.
Here is an example of how I would approach your problem, it's not going to be your code exactly but hopefully you can replicate the approach to work with you code:
import React, { useState } from 'react';
const Example = () => {
const [classes, setClasses] = useState('class-1');
const handleToggleClasses = () => {
setClasses(classes === 'class-1' ? 'class-2' : 'class-1')
}
return (
<>
<div className={classes}>
my classes will change when the button is clicked
</div>
<button onClick={handleToggleClasses}>
click me to toggle classes
</button>
</>
)
}
This button in this code has a an onClick handler which is equivalent to assigning it an event listener using vanilla JS like you did in your useEffect and I pass to it the handleToggleClasses function which just toggles between the classes using useState to keep track of that. It's cleaner, more performant and concise.
you can read more about handling events here
I hope that helps!
I currently have my nav set up how i'd like, I would just like the logo image to shrink from 91px to 60px when the user scrolls down the page, and then grow back to 91px when they're at the top. I've seen some questions online but none of them seem to work or be specific enough for the solution I want. Any help would be really appreciated. Updated my code with my attempt from this codesandpit from this question - Resize Header onscroll React
When I scroll down I get this error -
TypeError: headerEl is null
import React, { Component } from "react";
import logo from "../images/sdrlogo.jpeg";
import { FaAlignRight } from "react-icons/fa";
import { Link } from "react-router-dom";
export default class Navbar extends Component {
state = {
isOpen: false,
}
handleToggle = () => {
this.setState({ isOpen: !this.state.isOpen });
}
componentDidMount() {
window.addEventListener("scroll", this.resizeHeaderOnScroll);
}
resizeHeaderOnScroll() {
const distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 200,
headerEl = document.getElementById("js-header");
if (distanceY > shrinkOn) {
headerEl.classList.add("smaller");
} else {
headerEl.classList.remove("smaller");
}
}
render() {
return <nav className="navbar">
<div class="nav-center">
<div class="nav-header">
<Link to="/">
<img className="logo" src={logo} alt="Derby Golf Centre" />
</Link>
<button type="button" className="nav-btn" onClick={this.handleToggle}>
<FaAlignRight className="nav-icon" />
</button>
</div>
<ul className={this.state.isOpen ? "nav-links show-nav" : "nav-links"}>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/lesson">Book a Lesson</Link>
</li>
<li>
<Link to="/opening-times">Opening Times</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
<li>
<Link to="/driving-range">Driving Range</Link>
</li>
</ul>
</div>
</nav>;
}
}
So, I took some time and went through the code. I missed the CSS file on codesandbox, I've amended my code and using getElementbyID, I change the logo from a class to an ID and then used that. In the CSS I created a class called logoShrink and added transitions to both.
.logoShrink {
height: 60px !important;
transition: 0.5s;
}
if anyone is bothered, code is below!
import React, { Component } from "react";
import logo from "../images/sdrlogo.jpeg";
import { FaAlignRight } from "react-icons/fa";
import { Link } from "react-router-dom";
export default class Navbar extends Component {
state = {
isOpen: false,
}
handleToggle = () => {
this.setState({ isOpen: !this.state.isOpen });
}
componentDidMount() {
window.addEventListener("scroll", this.resizeHeaderOnScroll);
}
resizeHeaderOnScroll() {
const distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 100,
headerEl = document.getElementById("logo");
if (distanceY > shrinkOn) {
headerEl.classList.add("logoShrink");
} else {
headerEl.classList.remove("logoShrink");
}
}
render() {
return <nav className="navbar">
<div class="nav-center">
<div class="nav-header">
<Link to="/">
<img id="logo" src={logo} alt="Derby Golf Centre" />
</Link>
<button type="button" className="nav-btn" onClick={this.handleToggle}>
<FaAlignRight className="nav-icon" />
</button>
</div>
<ul className={this.state.isOpen ? "nav-links show-nav" : "nav-links"}>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/lesson">Book a Lesson</Link>
</li>
<li>
<Link to="/opening-times">Opening Times</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
<li>
<Link to="/driving-range">Driving Range</Link>
</li>
</ul>
</div>
</nav>;
}
}
I have been scouring the Internet to achieve this effect, but the closest I got was this very helpful blog article by Phuc. Attaching the link with this answer, see if it helps you.
The outcome of following his code would be —
Slight shrinkage of the Navbar
Reduction of opacity of the background of the Navbar
Blurring of the background of the section of the page that gets behind the Navbar
It is a neat effect which can be used (with a few changes) to suit your exact purpose.
I have created a basic React project that is pulling data from a SQL server. I would like this to be able to be rendered conditionally depending on what button has been clicked.
This is my Display Users Component which is used within my AdminViewUsers component (What is actually displaying the users).
import React, { Component } from 'react';
import './customers.css';
class DisplayUsers extends React.Component{
constructor(){
super();
this.state= { users: [] }
}
componentDidMount(){
this.setState({
users: this.getItems()
})
}
getItems(){
fetch('/admin-view-users')
.then(recordset => recordset.json())
.then(results => { console.log(results.recordset); this.setState({'users': results.recordset}); });
}
render () {
console.log(this.state.users)
return (
<ul>
{this.state.users && this.state.users.map(function(user, index){
//if (user.severity === 1){
return(
<div className ="jumbotron">
<li>
Severity: {user.severity}
</li>
<li>
<p>User Name:{user.name} </p>
</li>
<li>
User Email: {user.email}
</li>
<li>
Description of Issue: {user.description}
</li>
<button>See Details</button>
</div>
)
})
}
</ul>
);
}
}
export default DisplayUsers;
This is my AdminViewUsers Component
import logo from '../codestone logo.png';
import {Link } from 'react-router-dom'
import '../bootstrap.min.css'
import '../bootstrap.min.css'
import '../App.css'
import Customers from "../Components/customers";
import DisplayUsers from "../Components/DisplayUsers";
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, DropDownButton } from 'reactstrap';
function Home() {
return (
<div>
<Header/>
<SeveritySelector/>
<DisplayUsers/>
</div>
);
}
function Header(){
return (
<div class="jumbotron">
<div className = "User-Menu">
<Link>User details </Link>
</div>
<img className='profile-image' alt='icon' src={logo} width="340" height="60"/>
<Navigation/>
</div>
)
}
function Navigation (){
return(
<div>
<br/>
<div class="btn-group">
<Link to= '/home'><button type="button" class="btn btn-light">Home</button></Link>
<Link to= '/admin-view-users'><button type="button" class="btn btn-light">View Users(Admin)</button></Link>
</div>
</div>
)
}
function SeveritySelector (){
return(
<div className = "Severity-Toolbar">
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group mr-2" role="group" aria-label="First group">
<button type="button" class="btn btn-secondary">Severity High</button>
<button type="button" class="btn btn-secondary">Severity Medium</button>
<button type="button" class="btn btn-secondary">Completed</button>
<button type="button" class="btn btn-secondary">View All</button>
</div>
</div>
</div>
)
}
export default Home;
Essentially I would like to use the function Severity Selector to be the decider of how the statement is displayed.E.g If the high severity button is selected then it will display all with a high severity (1) if medium selected all with medium severity (2) and completed to have a severity of 3. Finally a button to display all.
What in your opinion is the best way to do this? I understand I could use multiple statements within my "server.js" and load different queries and have them connected to different pages.
But is there a way that I could just use a if statement or something similar to determine what button is selected to avoid multiple transactions with the server? You can see a brief attempt I had within the display users with an if statement which worked but just was not dependent on the buttons.
Conditional render can be achieved using various techniques, the most used is the bracket style variant. It can be used in the following way:
function Header(){
const showFirst = true;
return (
<div class="jumbotron">
{showFirst && <MyFirstComponent />}
{!showFirst && <MySecondComponent />}
</div>
)
}
This will render the <MyFirstComponent /> if showFirst is true and will show <MySecondComponent /> if it is false.
I am following a tutorial that creates an animated navbar and hamburger manu using css, html and javascript, and I want to create the navbar as a react component for my project.
The code that I am trying to covert is the following, which is an app.js file which is embedded in the html with tags:
const navSlide = () => {
const burger = document.querySelector('.burger');
const nav = document.querySelector('.nav-links');
burger.addEventListener('click', () => {
nav.classList.toggle('nav-active');
})
}
navSlide();
I have tried to implement this code into my navbar react component as follows:
import React from "react";
const NavBar = () => {
const nav = document.querySelector(".nav-links");
return (
<div className="navbar">
<nav>
<ul className="nav-links">
<li>
Menu Item
</li>
</ul>
<div
className="burger"
onClick={() => {
nav.classList.toggle("nav-active");
}}
>
<div className="line1" />
<div className="line2" />
<div className="line3" />
</div>
</nav>
</div>
);
};
export default NavBar;
However this returns the error of:
"TypeError: Cannot read property 'classList' of null"
The CSS of .nav-active is as follows:
.nav-active {
transform: translateX(0%);
}
The result of this I am expecting is for the navbar to toggle open and closed when the burger symbol is clicked
The best option is to go with state. This is should work, have not tested though. ReactJS 16.8 is required for useState hook to work.
import React, {useState} from "react";
const NavBar = () => {
const [navOpened, setNavOpened] = useState(false);
const navClassNames = navOpened ? 'nav-links nav-active' : 'nav-links';
return (
<div className="navbar">
<nav>
<ul className={navClassNames}>
<li>
Menu Item
</li>
</ul>
<div
className="burger"
onClick={() => setNavOpened(!navOpened)}
>
<div className="line1" />
<div className="line2" />
<div className="line3" />
</div>
</nav>
</div>
);
};
To refer to DOM elements you should be using ref, you can use a useRef hook docs.
import React, { useRef } from "react";
const NavBar = () => {
const nav = useRef(null); // initial value of ref null
return (
<div className="navbar">
<nav>
<ul className="nav-links" ref={nav}> {/* Put the ref in your JSX */}
<li>
Menu Item
</li>
</ul>
<div
className="burger"
onClick={() => {
nav.current.classList.toggle("nav-active"); // Now you can use the ref here, current is required to get the current value of the ref
}}
>
<div className="line1" />
<div className="line2" />
<div className="line3" />
</div>
</nav>
</div>
);
};
export default NavBar;