I am trying to make responsive menu bar where the menu needs to be displayed and hidden. It is not working as expected. So, I did the simple demo version to check if it works, but it does not work as well. Please let me know why it is not working.
import { useState } from "react";
import "./styles.css";
export default function App() {
const [show, setShow] = useState(true);
console.log("Show value: ", show);
const menuToggle = () => {
setShow(!show);
};
return (
<div className="App">
<div>
<button type="button" onClick={menuToggle}>
Show
</button>
<button type="button" onClick={menuToggle}>
Hide
</button>
</div>
<h1>Hello World</h1>
</div>
);
}
And styles.css is as follows:
.App {
font-family: sans-serif;
text-align: center;
}
h1 {
opacity: ${({ show }) => (show ? 1 : 0)};
}
However, when I set opacity directly as 1 or 0, then it works. It makes me think that the CSS property is not set on component re-rendering. Please correct me where I am going wrong.
Edit:
In my actual project, I need to use styled component and have it under @media screen. Part of my code is:
<NavMenu>
{data.map((elementList, index) => (
<NavItem key={index}>
<NavLinks to={elementList.to}>{elementList.text}</NavLinks>
</NavItem>
))}
</NavMenu>
and the component NavMenu is defined as:
export const NavMenu = styled.ul`
width: 100%;
display: flex;
text-align: center;
list-style: none;
align-items: center;
justify-content: center;
@media screen and (max-width: 960px) {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100vh;
position: fixed;
top: 0;
right: 0;
opacity: ${({ show }) => (show ? 1 : 0)};
visibility: ${({ show }) => (show ? "visible" : "hidden")};
transform: translateY(${({ show }) => (show ? "0" : "-100vh")});
transition: transform 5s ease;
background-color: #071c2f;
}
Thanks
3
Answers
Try applying the conditional styling directly in your
JSX
.You can render conditionally the whole class of css, I think that’s the best approach and no matter the number of classes you can render them conditionally.
Example:
I get confused with what you mean by it is not working as expected, do you want to always show the menu bar in large screen and controls it in smaller screen?. About using media queries in react JS, I personally suggest you to use a CSS framework that supports media queries and handle the state the react way.
If you insist to do media queries with react JS, this is what I come up with.
the code above is the parent component. The component watch for the screen changes that happens in user’s web browsers.
as for the trigger, the component controls the state of the navbar visibility on screen below 960px.
the nav accept two state, one is from mediaqueries and one is current open state. So even if the open state is
false
, in large screen (above 960px) the navbar will always be visible.You can later stylize the navbar component with class or inline style. It should not affect the functionality.