I have a state in React
// sidebar toggled
const [sidebarToggled, setSidebarToggled] = useState(false);
sidebarToggled(false) = sidebar is visible
sidebarToggled(true) = sidebar is hidden
I have a button that toggles the sidebar
<button onClick={()=>setSidebarToggled(!sidebarToggled)}>Toggle</button>
Expected Behaviour
When I am on a desktop screen (larger than 768px), sidebarToggled is true, which means the sidebar is visible, and when I am using Chrome console to check responsiveness or by minimizing and maximizing the screen, when the screen is less than 768px sidebarToggled is set to true to make the sidebar hidden and when it is larger than 768px sidebarToggled is set to false to make it visible again. It is working and I achieved this by following code
// toggle sidebar when screen reaches 768px
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 768) {
setSidebarToggled(true);
}
else{
setSidebarToggled(false);
}
};
// Add event listener for window resize
window.addEventListener('resize', handleResize);
// Cleanup the event listener on component unmount
return () => window.removeEventListener('resize', handleResize);
}, []);
Now comes the main point
If I set the sidebarToggled to true by clicking the button from a device larger than 768px then no matter what screen size we have sidebarToggled should always remain true and the sidebar should always remain hidden. Similarly if from a mobile device I set the sidebarToggled to false then minimizing or maximizing should have no effect on sidebarToggled, it should always remain false and visible.
http://webapplayers.com/homer_admin-v2.0/index.html
This behavior from the above site is what I want in my React App.
Conceptually you have two pieces of state.
You cannot and need not represent both as one boolean. Split the state in two and derive the UI state from the two state variables. Here I've extracted the logic into a hook.
const useSidebarState = (widthThreshold = 768) => {
const [sidebarExplicitlyHidden, setSidebarExplicitlyHidden] = useState(null);
const [screenWidthAboveThreshold, setScreenWidthAboveThreshold] = useState(
window.innerWidth > widthThreshold
);
useEffect(
() => {
const handleResize = () => void setScreenWidthAboveThreshold(
window.innerWidth > widthThreshold
);
handleResize();
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
},
[widthThreshold]
);
const toggleSidebar = useCallback(
() => void setSidebarExplicitlyHidden(prevValue => !prevValue)
);
return {
sidebarToggled: sidebarExplicitlyHidden ?? !screenWidthAboveThreshold,
toggleSidebar
};
};
Pass toggleSidebar
as an click handler to your toggle button.