Below is the code that I am trying to convert.
document.addEventListener("scroll", function() {
const links = document.querySelectorAll(".nav-link");
for (const l of links) l.classList.toggle('scrolling', window.scrollY > 0);
})
the thing is, I intend to change the color of all my links when the page is scrolling. That said, I could have used an if-else statement instead, but using an if-else statement would only make the color of the first link to change instead. so forEach statement is the most appropriate method.
The above code was converted to react like this as shown below.
const [isLinkScrol, setIsLinkScrol] = useState(false);
const linkScroll = setLinkScrol(
for (const l of links) l.classList.toggle( window.scrollY > 0);
);
useEffect(() => {
document.addEventListener('scroll', linkScroll);
return () => {
document.removeEventListener('scroll', linkScroll);
};
},[]);
return (
<ul className={`nav_links ${isNavShowing ? "show_nav" : "hide_nav"}`}>
{
links.map(({name, path }, index) => {
return (
<li key={index}>
<NavLink to={path} className={({isActive}) => isActive ? "active-nav" : ""} onClick={() => setIsNavShowing (prev => !prev)}>{name}</NavLink>
</li>
)
})
}
</ul>
)
however, there seams to be an error here,
setIsLinkScrol(
for (const l of links) l.classList.toggle( window.scrollY > 0);
);
which I have not been able to wrap my head around
You can't pass the setIsLinkScrol
setter to addEventListener
as you will set the complete Event to the state, you don't want/need that.
Instead, make a onScoll
function that will cal setState
with window.scrollY
.
Then you can add a className
to some element(s) if the scollValue > 0
Small demo:
const { useState, useEffect } = React;
const Example = () => {
const [scollValue, setScrollValue] = useState(0);
const onScroll = (e) => setScrollValue(window.scrollY);
useEffect(() => {
document.addEventListener('scroll', onScroll);
return () => document.removeEventListener('scroll', onScroll);
}, [])
return (
<div>
<h1>{'Example'}</h1>
{[...Array(50)].map((e, i) => (
<span className={scollValue > 0 ? 'scrolling' : ''} key={i}>Some content</span>
))}
</div>
)
}
ReactDOM.render(<Example />, document.getElementById("react"));
div { display: flex; flex-direction: column }
.scrolling { color: orange; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
{[...Array(50)].map((e, i) => (
<span className={scollValue > 0 ? 'scrolling' : ''} key={i}>Some content</span>
))}
Here I use [...Array(50)].map
to create the same element 50 times
How to repeat an element n times using JSX and Lodash
Then we use an Conditional (ternary) Operator to set the class if needed.