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><a href="#">Blog</a></li>
<li><a href="#">What's New</a></li>
<li><a href="#">Categories</a></li>
</ul>
<ul>
<li><a href="#">Projects</a></li>
<li><a href="#">News</a></li>
<li><a href="#">Store</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></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">
<a href="#" className="logo"><img src="/logo.png" alt="logo" /></a>
<div className="container-inner">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Home</a></li>
<li><a href="#">Home</a></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
CodePudding user response:
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!
CodePudding user response:
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…
CodePudding user response:
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.