Reputation: 808
I know this should be stupid simple. All of the examples I can find on here are stupid simple. But for some reason I can't get a className to change conditionally in my component.
I'm trying to animate the site logo when the user scrolls down. fullLogo
is changing as expected according to the logs. But the class never changes. The only thing I can think is that once the render happens that's it, and it needs to be declared as a class in order to re-render like that. Is that the issue?
const headerHeight = 89
let fullLogo = true
window.addEventListener('scroll', (e) => {
if (window.pageYOffset > headerHeight) {
console.log('scrolled beyond header height')
fullLogo = false;
} else {
fullLogo = true;
}
console.log('fullLogo', fullLogo)
})
<header className={(!!fullLogo ? 'full-logo' : '')}>
Here's the full component if that helps:
import React, { useState } from "react"
import PropTypes from "prop-types"
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
NavItem,
NavLink
} from 'reactstrap'
import "./header.scss"
const Header = ({ siteTitle, menu, location }) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
const headerHeight = 89
let fullLogo = true
window.addEventListener('scroll', (e) => {
if (window.pageYOffset > headerHeight) {
console.log('scrolled beyond header height')
fullLogo = false;
} else {
fullLogo = true;
}
console.log('fullLogo', fullLogo)
})
menu.forEach((item, index) => {
if (item.path === location.pathname) {
item.active = true
} else {
item.active = false
}
})
return (
<header className={(!!fullLogo ? 'full-logo' : '')}>
<Navbar color="light" light expand="md" fixed="top">
<NavbarBrand href="/">
<span className="initial">L</span>
<span className="rest">OGO</span>
<span className="splitter"></span>
<span className="initial">N</span>
<span className="rest">AME</span>
</NavbarBrand>
<NavbarToggler onClick={toggle} />
<Collapse isOpen={isOpen} navbar>
<Nav className="mr-auto" navbar>
{menu.map((item, index) => (
<NavItem key={`nav_link_${index}`}>
<NavLink href={item.path} className={item.active ? `active` : null}>{item.title}</NavLink>
</NavItem>
))}
</Nav>
</Collapse>
</Navbar>
</header>
)
}
Header.propTypes = {
siteTitle: PropTypes.string,
menu: PropTypes.array
}
Header.defaultProps = {
siteTitle: ``,
menu: {
title: `Home`,
path: `/`
}
}
export default Header
Upvotes: 1
Views: 462
Reputation: 342
The code by using hooks be like
import React, { useState } from "react"
import PropTypes from "prop-types"
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
NavItem,
NavLink
} from 'reactstrap'
import "./header.scss"
const Header = ({ siteTitle, menu, location }) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
const headerHeight = 89
const [fullLogo,setFullLogo] = useState(true)
window.addEventListener('scroll', (e) => {
if (window.pageYOffset > headerHeight) {
console.log('scrolled beyond header height')
setFullLogo(false);
} else {
setFullLogo(true);
}
console.log('fullLogo', fullLogo)
})
menu.forEach((item, index) => {
if (item.path === location.pathname) {
item.active = true
} else {
item.active = false
}
})
return (
<header className={(!fullLogo ? 'full-logo' : '')}> //If You Want to toggle current state
<Navbar color="light" light expand="md" fixed="top">
<NavbarBrand href="/">
<span className="initial">L</span>
<span className="rest">OGO</span>
<span className="splitter"></span>
<span className="initial">N</span>
<span className="rest">AME</span>
</NavbarBrand>
<NavbarToggler onClick={toggle} />
<Collapse isOpen={isOpen} navbar>
<Nav className="mr-auto" navbar>
{menu.map((item, index) => (
<NavItem key={`nav_link_${index}`}>
<NavLink href={item.path} className={item.active ? `active` : null}>{item.title}</NavLink>
</NavItem>
))}
</Nav>
</Collapse>
</Navbar>
</header>
)
}
Header.propTypes = {
siteTitle: PropTypes.string,
menu: PropTypes.array
}
Header.defaultProps = {
siteTitle: ``,
menu: {
title: `Home`,
path: `/`
}
}
export default Header
Upvotes: 2
Reputation: 94
Your assumption is correct. There's no lifecycle event that's triggering a re-render. Functional components only update if you change props or use hooks. Here you could use a hook to setDisplayFullLogo.
Upvotes: 2