problem with the clientHeight attribute in window event handlers

The component below is designed to react to changes in window resize based on the container height.

However, there seems to be an issue where the containerHeight variable increases as the window size decreases, but does not decrease when I make the window size bigger. It remains at its last maximum value. *** What's confusing is that if I remove the "line-height: 1.25rem;" from the code-container class, everything works perfectly!

Some notes:

  1. I am using debouncing on the resize handler to prevent frequent calculations.
  2. Flexbox is being used for the code-container and line-numbers classes.

import { useState, useEffect, useRef } from "react";
import styles from "./CodeBlock.module.css";

function debounce(fn, ms) {
  let timer;
  return (_) => {
    clearTimeout(timer);
    timer = setTimeout((_) => {
      timer = null;
      fn.apply(this, arguments);
    }, ms);
  };
}

const CodeBase = (props) => {
  const codeContainerRef = useRef(null);
  const [lineCount, setLineCount] = useState(0);

  useEffect(() => {
    const debouncedHandleResize = debounce(() => {
      const lineHeight = 20; // Value based on CSS
      const containerHeight = codeContainerRef.current.clientHeight;
      console.log(containerHeight);
      const calculatedLineCount = Math.floor(containerHeight / lineHeight);
      setLineCount(calculatedLineCount);
    }, 500);
    debouncedHandleResize();
    window.addEventListener("resize", debouncedHandleResize);
    return () => {
      window.removeEventListener("resize", debouncedHandleResize);
    };
  }, []);

  return (
    <div className={styles["code-container"]} ref={codeContainerRef}>
      <div className={styles["line-numbers"]}>
        {Array.from({ length: lineCount }, (_, index) => (
          <div key={index + 1} className={styles["line-number"]}>
            {index + 1}
          </div>
        ))}
      </div>
      <div className={styles["code-line"]}>{props.children}</div>
    </div>
  );
};

export default CodeBase;

And here is the CSS code:

    .code-container {
      display: flex;
      line-height: 1.25rem;
    }
    
    .line-numbers {
      display: flex;
      flex-direction: column;
      max-height: 100%; /*Ensure it doesn't exceed container height */
    }
    
    .line-number {
      color: #777;
      font-size: 12px;
    }
    
    .code {
      overflow-x: auto;
      white-space: pre-wrap;
    }
    
    .code-line {
      padding-left: 8px; /* Add spacing between line numbers and code */
    }

Answer №1

If you encounter this issue, it is likely because you are using an import statement in a setting that does not support ES Modules. This could happen in environments like browsers that lack module support.

import React, { useState, useEffect, useRef } from "react";
import styles from "./CodeBlock.module.css";

function debounce(fn, ms) {
  let timer;
  return (_) => {
    clearTimeout(timer);
    timer = setTimeout((_) => {
      timer = null;
      fn.apply(this, arguments);
    }, ms);
  };
}

const CodeBlock = (props) => {
  const codeContainerRef = useRef(null);
  const [lineCount, setLineCount] = useState(0);

  useEffect(() => {
    const debouncedHandleResize = debounce(() => {
      const lineHeight = 20; // Value based on CSS
      const containerHeight = codeContainerRef.current.clientHeight;
      const calculatedLineCount = Math.floor(containerHeight / lineHeight);
      setLineCount(calculatedLineCount);
    }, 500);
    
    debouncedHandleResize();
    window.addEventListener("resize", debouncedHandleResize);
    return () => {
      window.removeEventListener("resize", debouncedHandleResize);
    };
  }, []);

  return (
    <div className={styles["code-container"]} ref={codeContainerRef}>
      <div className={styles["line-numbers"]}>
        {Array.from({ length: lineCount }, (_, index) => (
          <div key={index + 1} className={styles["line-number"]}>
            {index + 1}
          </div>
        ))}
      </div>
      <div className={styles["code-line"]}>{props.children}</div>
    </div>
  );
};

export default CodeBlock;

To resolve the issue in your CSS code, make sure to update your class names...

/* CodeBlock.module.css */
.code-container {
  display: flex;
  line-height: 1.25rem;
}

.line-numbers {
  display: flex;
  flex-direction: column;
  max-height: 100%; /* Ensure it doesn't exceed container height */
}

.line-number {
  color: #777;
  font-size: 12px;
}

.code-line {
  padding-left: 8px; /* Add spacing between line numbers and code */
}

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

Setting up redux with Next.js: a step-by-step guide

After setting up redux in this manner, everything is functioning properly. The _app.js file has been reorganized as follows : import App from 'next/app'; import { Provider } from 'react-redux'; import withRedux from 'next-redux-wr ...

Handling exceptions in Node.js is an essential part of writing reliable

Just a quick question: I seem to be dealing with an incorrect endpoint, and every time I run the code below, it results in an exception being thrown client.post("http://WrongEndPoint", [], function (data, response) { console.log("data:", data, "respo ...

How to choose an option from a dropdown menu using React

In a React application, I am creating a straightforward autocomplete feature. The code is outlined below. index.js import React from 'react'; import { render } from 'react-dom'; import Autocomplete from './Autocomplete'; co ...

Tips for Implementing a "Please Hold On" Progress Bar in ASP.NET

I have a master page named siteMaster.master, an aspx page called submission.aspx, and a user control named attachment.ascx. The script manager is included in my master page. The submission page inherits the master page and registers the user control attac ...

Using NodeJS and Express together with Ajax techniques

I am currently developing a web application that utilizes Ajax to submit a file along with some form fields. One unique aspect of my form is that it allows for dynamic input, meaning users can add multiple rows with the same value. Additionally, the form i ...

Vue component lifecycle hook to fetch data from Firebase

Looking for a solution with Vue 2 component that utilizes Vuefire to connect declaratively with a Firebase real-time database: import { db } from '../firebase/db' export default { data: () => ({ cats: [] }), firebase: { ...

Tips for retrieving the HTML file of a modified canvas in HTML5

I’m currently working on a project to develop a website that allows users to design their own pages by simply dragging and dropping elements onto the canvas. The goal is for users to be able to save their creations as an HTML file. I’m facing challen ...

Mobile Safari on iOS devices is known for its capability to overlay HTML5 <video> on top of everything

Although a similar question was asked 6 years ago without any answers, I am currently facing the same issue. Problem: The <video> tag in my Angular/Ionic application overlaps my image and two buttons in iOS Mobile Safari - no matter what I try! It ...

The printed Bootstrap web page is being truncated

I have a unique dynamic webpage created with Bootstrap that needs to be printable. I am implementing media queries for styling the page when printing: /** Custom Print Styles **/ @media print { header, .menu, footer { display: none; ...

Ensure that the Javascript file is included before the CSS file to prevent any margin

I have external files for JavaScript and CSS. According to This question, they suggested that including JavaScript before CSS could enhance performance. However, I noticed a discrepancy in Chrome when I load JS before CSS - the .offset() function returns a ...

What is the best way to preserve the background color of nested progress bars?

In this scenario, I am attempting to apply border-radius specifically to the upper and lower right corners of the progress bars. The idea is to create a cascading effect where each color (red, green, and blue) progress bar overlaps slightly with the next o ...

Ways to add more spacing between list items without affecting the position of the bottom div

I'm attempting to achieve a layout similar to an Instagram post, where the list expands but does not push the footer down. In my case, adding margin-bottom to the comment class affects the height of the <div class="post-details-container" ...

Encountering an NPM ELIFECYCLE error when attempting to start the node server with the

After following the instructions on deploying test-bot on IBM Watson from this link https://github.com/eciggaar/text-bot, I encountered errors while attempting to deploy the code locally using CLI foundry. My setup includes Node.js version 6.10.3 and npm ...

Guide on Organizing Information in Next.js

I have an online store and I am looking to organize my data by categories. Initially, I tried using APIs for this purpose but it ended up putting a strain on my server. So now, I am attempting to use Redux to store the data and filter it from there. Howeve ...

Scroll to make the div slide in from the bottom

I'm trying to achieve a similar effect like the one shown in this website (you need to scroll down a bit to see the divs sliding in). Although I'm not very proficient in JS, I was able to create a code that makes the divs fade in from 0 opacity ...

React: Modifying state based on information received from a child component

One dilemma I'm facing involves a child component on my page that contains an input. The goal is to extract the value entered into this input box and use it to update the parent's state. In essence, when a user types in a name and presses enter, ...

Node.js is essential when using Angular for implementing ui-select components

I'm currently delving into learning AngularJS. I've successfully created a basic web application using AngularJS, with Java EE powering the backend (server side). This app is being hosted on Tomcat. The advantages of AngularJS over JQuery are bec ...

Unable to retrieve content in NGX-Quill upon submission

I am currently using "ngx-quill": "^14.3.0" along with "@angular/core": "~12.2.0". It is registered in the app module: QuillModule (not for root). And also in the lazy loaded module: QuillModule (not for root). public editor = { toolbar: [ ...

When trying to convert to JSON in node, the process fails. However, the data can still be

I am currently working on converting an array to JSON in order to send it to a client. The data I see in the console is as follows: [ NL: [ true, true, true, true, true, true, true, true, true, true, true, true ], ...

Angular $resource encounters a 400 Bad Request error when attempting a PUT request, triggering the $resolve and $promise

My service is structured as follows (with variables removed): angular .module('app') .factory('Employee', function($resource) { return $resource("https://api.mongolab.com/api/1/databases/:dbName/collections/:collectionN ...