Resizing a scrollable list using React Refs and UseLayoutEffect

Essentially, my issue stems from having a scrollable list with a set maximum height of '100vh'. I also have a detail card beside the list that contains accordion components. When one of these accordions is expanded, it increases the height of the card and subsequently the entire page. However, the scrollable list remains locked at its original maxHeight of 100vh, which now only reaches halfway down the page. Is there a way to dynamically reset the maxHeight based on the updated page height? It's important to note that I am using material ui (JSS) for styling.

My current approach:

const List = ({ match }) => {
  
  const [height, setHeight] = useState(0)
  const ref = useRef(null)

  console.log(ref)
  

  
  useLayoutEffect(() => {
    setHeight(ref.current.clientHeight) 
  }, [])

  
  return (
    <div className={classes.root}>
     
        <Grid container justify="center" >
          <Grid item xs={10} className={classes.filter}>
            {renderFilter()}
          </Grid>
        </Grid>
        <Grid container justify='center' className={classes.cardGrid}>
        {!matches ? <Grid item xs={3} md={3} lg={3} style={{maxHeight: Math.max(height, '100vh')}} className={classes.list}>
            <List>{renderedList()}</List>  
        </Grid> : drawer}
        <Grid item lg={1} md={1} sm={0} xs={0}/>
        <Grid item xs={10} md={6} lg={6}  ref={ref} className={classes.detail}>
          {renderDetail()}
        </Grid>
    
        </Grid>
    </div>
  );
};

export default SongList;

Answer №1

I implemented a solution utilizing a custom hook in conjunction with the useRef feature:

The custom hook code snippet is as follows:

import { useState, useEffect, useCallback } from "react";

function useHeight(elementRef) {
  const [height, setHeight] = useState(null);

  const updateHeight = useCallback(() => {
    if (elementRef && elementRef.current) {
      const { height } = elementRef.current.getBoundingClientRect();
      setHeight(height);
      
    }
  }, [elementRef]);

  useEffect(() => {
    updateHeight();
    window.addEventListener("transitionstart", updateHeight);
    return () => {
      window.removeEventListener("transitionstart", updateHeight);
    };
  }, [updateHeight]);
  return [height];
}

export default useHeight;

The component where this custom hook is utilized looks like this:

const List = ({ match }) => {
  const elementDOM = useRef(null);
  const [height] = useHeight(elementDOM);

  
  return (
    <div className={classes.root}>
     
        <Grid container justify="center" >
          <Grid item xs={10} className={classes.filter}>
            {renderFilter()}
          </Grid>
        </Grid>
        <Grid container justify='center' className={classes.cardGrid}>
        {!matches ? <Grid item xs={3} md={3} lg={3}  className={classes.list}>
            <List style={{minHeight: '100vh', height: height}}>{renderedList()}</List>  
        </Grid> : drawer}
        <Grid item lg={1} md={1} sm={0} xs={0}/>
        <Grid item xs={10} md={6} lg={6}  ref={elementDOM} className={classes.detail}>
          {renderDetail()}
        </Grid>
    
        </Grid>
    </div>
  );
};

export default SongList;

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

Creating packaging for a node-webkit application

https://github.com/rogerwang/node-webkit/wiki/How-to-package-and-distribute-your-apps When I was packaging my node-webkit application for Windows using the instructions provided in the above link, I encountered a challenge. I could not figure out how to p ...

Utilize resources from webpack's bundled npm package assets

I've been racking my brain over this issue for quite some time now, and I'm starting to wonder if it's even achievable. Any assistance on this matter would be greatly appreciated! The npm dilemma I have an npm package that serves as a coll ...

Can one initiate a server within Zapier Code?

Is there a way to send an HTTP CODE = 200 with a response body of 'OK' when receiving a notification on Zapier? I attempted to use the following code snippet in Zapier: var http = require('http'); const server = http.createServer((r ...

The issue of AngularJS inline style color not functioning in Internet Explorer 11 has been identified

Hello, I am currently attempting to dynamically change the color of a p tag. However, I am facing issues with IE-11 not supporting this functionality. How can I resolve this problem? <p style="color:{{userData.color}} !important;">{{userData.someTex ...

The success variable of the Ajax running continuously in a loop is not being refreshed

Within this code snippet, a for loop is utilized to iterate through an array called netnos[] and update the variable 'nets' for each item. Ajax is then invoked to call a PHP script that generates a listing, which is successfully outputted to the ...

Achieving the Clean Architecture with React and Redux by integrating separation of concerns

Recently, I've been delving into the realm of Clean Architecture as I tackle a problem. Specifically, I've been pondering over how to integrate Redux with React. The usual approach involves wrapping our app component with a provider like so: Reac ...

Is Redux really the new trend in the world of action creators?

I am new to this. I'm a bit unsure, is it okay or silly to use the pattern below? import { createAction, handleActions } from "redux-actions"; const CHANGE_STATE = "appState/CHANGE_STATE"; export const changeState = createAction(CHANGE_STATE, (key, ...

Display the HTML/CSS layout following the JavaScript window.open action

Encountering issues with printing output in an opened window using JavaScript. I'm creating a new document through window.open and including CDN links to Bootstrap files. While everything appears fine in the opened window, when attempting to print (XP ...

What is the best way to send multiple id values with the same classname as an array to the database via AJAX in Codeigniter?

Hey everyone, I'm facing an issue where I need to send multiple IDs with the same class name but different ID values to the database using AJAX. However, when I try to do this, only the first value is being picked up and not all of them. How can I suc ...

React Grid by DevExtreme

Does anyone have a solution for adjusting the fontSize of the TableHeaderRow in a DevExtreme React Grid? Here is some code from a specific website () that I've been exploring: import * as React from 'react'; // Other imports... const Ad ...

Creating three separate Material-UI text fields enclosed in a single border in a React JS application

I'm trying to add a dimensions box to my form. I created 3 MUI textfields within a formGroup, set the border radius to 0, and adjusted the color properties but it still didn't work. This is what I'm aiming for My goal is to have 3 input fie ...

How to achieve a Dropbox-inspired footer effect using CSS?

Take a look at dropbox's website here: Have you noticed how the footer with "Learn more" remains fixed at the bottom regardless of window resizing until you click or scroll down? position: absolute; bottom: 50px; left: 0; width: 100%; text-align: ce ...

Switching the checkbox value upon clicking a div element

One challenge I am facing is with a checkbox that saves its value and title in the local storage when clicked. This checkbox is located within a div, and I want the checkbox value to change whenever any part of the div is clicked. Despite my efforts, I hav ...

Unable to determine why node.js express path is not working

const express = require("express"); const app = express(); app.use(express.static("public")); var dirname = __dirname; app.get("/:lang/:app",function(req,res){ console.log(req.params.lang + " " + req.params.app); ...

The width of a CSS border determines its height, not its width

When I try to use border-width: 100px; to set the horizontal width to 100px, it ends up setting the height to 100px instead. Any help would be greatly appreciated. .border-top-green { border-top: 1px solid #4C9962; border-width: 100px; padding-t ...

The following middleware is not functioning properly on a local SSL server

When I run my Nextjs app without SSL using "next dev", the middleware functions as expected without any errors. However, if I attempt to run the app with SSL enabled, an empty middleware function triggers an error. The code for the middleware function (l ...

Showcase three elements next to each other on the same row (Photo Gallery, Description, and Contact Form)

I am attempting to showcase three divs in a single line while working on a Subtheme for the Drupal 8 Bootstrap Theme. These particular divs are fields nested within a view known as viewproducts. The divs include: Juicebox Photo Gallery; ...

Ways to incorporate JSON web token into every query string of my requests

Just recently, I grasped the concept of using JSON web tokens. Successfully, I can generate a JSON web token upon sign-in and have also established the middleware to authenticate my token and secure the routes that fall under the JSON verification middlewa ...

How to populate a database with Facebook data by utilizing AJAX post and PHP

I've been developing a Facebook Canvas game and had it running smoothly on my localhost along with a local database via phpMyAdmin. However, after moving it online, I've encountered an issue with the database. Previously, the game would grab pla ...

Utilize the grouping functionality provided by the Lodash module

I successfully utilized the lodash module to group my data, demonstrated in the code snippet below: export class DtoTransactionCategory { categoryName: String; totalPrice: number; } Using groupBy function: import { groupBy} from 'lodash&apo ...