Tips for implementing a toggle feature for the sidebar in React, allowing it to switch between being visible and hidden

In my React application, I am managing the state of a sidebar using the useState hook.

// sidebar toggled
const [sidebarToggled, setSidebarToggled] = useState(false);

When sidebarToggled is false, the sidebar is visible. When it is true, the sidebar is hidden.

To toggle the visibility of the sidebar, I have implemented a button with an onClick event handler.

<button onClick={()=>setSidebarToggled(!sidebarToggled)}>Toggle</button>

Desired Behavior:

I want the sidebar to be visible when the screen size is larger than 768px and hidden when it is smaller. This behavior should persist even if the screen size changes by resizing or minimizing/maximizing the window. To achieve this functionality, I wrote the following code snippet:

// 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);
  }, []);

The Key Point:

If the user manually toggles the sidebar while on a device larger than 768px, I want that state change to be permanent regardless of any screen size adjustments. Similarly, if the sidebar is toggled on a mobile device, its visibility should not be affected by screen size changes.

Link to reference site

The desired behavior described on the provided website is what I aim to replicate in my React application.

Answer №1

In terms of concept, there are two states to consider.

  1. The user-set preference when clicking a button
  2. Whether the screen size is above or below a certain threshold

Instead of combining both into one boolean, it's best to separate them into two states and derive the UI state from these variables. Below is an example where the logic is extracted into a custom 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
  };
};

Make sure to pass toggleSidebar as a click handler for your toggle button.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered while compiling CSS for a map with @each function in Sass

I am currently in the process of developing a set of classes to define image styles based on specific skills. Colors associated with each skill are stored in a map. $skills-color: ( default : #D8D8D8, 6 : #2E80EC, 5 : # ...

In the context of NextJs, the req.body is treated as an object within the middleware, but transforms

Here is the middleware function responsible for handling the origin and CORS: export async function middleware(request: NextRequest) { const requestHeaders = new Headers(request.headers) const origin = requestHeaders.get('origin') ?? '& ...

Design a table featuring button groups using Bootstrap styling

I'm currently using Bootstrap 4 and facing some issues while attempting to create a button group with multiple rows, similar to the design shown in the image provided below. The default button groups in Bootstrap appear to only support arranging butto ...

Text overflow occurs when content overflows the space of its container, causing the HTML element to

My English isn't the greatest, but I hope to convey the question clearly. I am attempting to create an editable text within a div. Typically, the text will overflow the size of the div, so I need to contain the text in the div using overflow:scroll. ...

Utilizing React JS: Displaying or Concealing Specific Components Based on the URL Path

Is there a way to dynamically change the navbar items based on the URL without having separate navbar components for each side? My current navbar design features 3 links on the left side and 3 links on the right, but I want to display only one side at a ti ...

Hide Popover when child component is clicked

In my component, I include a Popover: // HeaderMenu.tsx const HeaderMenu = () => { const ShowMenu = () => { return ( <div className={classes.profile}> <ul> <Notifications /> </ul> ...

Can one utilize Javascript to write in plain text format?

Currently, using JavaScript I have a plain text containing data that is displayed within my form tags. Everything is functioning correctly, but now I need to update the values inside the code of my form tags in order for the changes to also be reflected in ...

Consolidate code by implementing on selectmenu

I need assistance with handling multiple select menus on a View page Below is a snippet of the code: $(function() { var selectSpeed = $('#speed'), selectTest = $('#test'); selectSpeed.selectmenu(); selectTest.selectmenu() ...

Adjusting CSS to realign images on various screen types

I am facing an issue with displaying a background image on a static web page. The height appears differently on various LCD screens. How can I ensure that the height adjusts to approximately 80% of the area? I have tried giving a percentage in the style fo ...

How to position an absolute element beneath a fixed element

My website is experiencing a problem where the fixed header is overlapping an absolute paragraph on this page. Does anyone know how to resolve this issue? ...

Challenge encountered when converting React function component into a class component

I've developed a react functional component that aids in supporting authentication required routes with react-router. const PrivateRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( isAuthenticated() ? ...

React JS - easily customizable Material UI Datepicker

Having difficulty with the Datepicker component in Material UI. Is there a way to reset its field that I'm missing? I've checked out this issue but still need some assistance. Can anyone offer help? ...

I updated the color of my a:link using jQuery, but now my a:hover is not functioning as expected

Due to the readability issues of the navigation color against a specific image, I am looking to modify it for a particular page. Below is the HTML code: <div id='nav'> <ul> <li id='navBiog'> ...

Grid element content suddenly shifts when opened

I am facing a peculiar issue with my layout. When I specify grid-template-rows: 1fr 1fr and try to open the details element, instead of smoothly expanding downwards, it seems to "jump" into position. This odd behavior disappears when I use grid-template-ro ...

Table lines that are indented

I am currently in the process of transforming a standard HTML table into an indented version like this: Is there a way to hide the initial part of the border so that it aligns with the start of the text, even if I can't do it directly in HTML? ...

What is the process behind the creation of the class or id fields in HTML for Gmail and Quora? How are these

When using Gmail: <tr class="zA yO" id=":1t4"> While on Quora: <span id="ld_zpQ1Cb_27965"> What is the purpose behind this and what specific tool do they employ to achieve it? ...

Position the spinner in the center of the user's screen

I created my own spinner: '''' #spinner-bg-loading{ position: absolute; left: 50%; top: 25%; width: 80px; height: 80px; margin: -75px 0 0 -75px; border: 16px solid #FFFFFF; border-radius: 50%; border-top: 16px solid #1 ...

Troubleshooting challenges with a React web application and resolving the issues

Recently, I stumbled upon a React web application from GitHub that caught my interest. I followed the instructions and ran the code using "npm start" in the terminal before accessing it at http://localhost:8080/webpack-dev-server/. However, I encountered a ...

Ways to expand the search box in a navigation bar with Bootstrap 5

Recently delving into front-end development, I've been working on designing a webpage that includes a search box (you can view the jsfiddle here). I decided to borrow the navbar component from https://getbootstrap.com/docs/5.0/components/navbar/ and m ...

Error: Unable to locate the custom module - TS2307

We have recently taken over a Next + TypeScript website from another developer and are attempting to create a new component that is heavily based on an existing one. I have duplicated the entire component and its subfolders at the same level as the origina ...