Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

390
Visualizações
How to measure the height of a child and pass it to a parent in React?

I want to calculate the height of a component and send it to its parent when the page is loaded and resized.

I'm using the below reusable Hook to successfully measure the height of the div inside the header component. But how do I send the height calculated from useDimensions in the child to its parent component as headHeight?

Measuring Hook

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

function getDimensionObject(node) {
  const rect = node.getBoundingClientRect();

  return {
    width: rect.width,
    height: rect.height,
    top: 'x' in rect ? rect.x : rect.top,
    left: 'y' in rect ? rect.y : rect.left,
    x: 'x' in rect ? rect.x : rect.left,
    y: 'y' in rect ? rect.y : rect.top,
    right: rect.right,
    bottom: rect.bottom
  };
}

export function useDimensions(data = null, liveMeasure = true) {
  const [dimensions, setDimensions] = useState({});
  const [node, setNode] = useState(null);

  const ref = useCallback(node => {
    setNode(node);
  }, []);

  useEffect(() => {
    if (node) {
      const measure = () =>
        window.requestAnimationFrame(() =>
          setDimensions(getDimensionObject(node))
        );
      measure();

      if (liveMeasure) {
        window.addEventListener('resize', measure);
        window.addEventListener('scroll', measure);

        return () => {
          window.removeEventListener('resize', measure);
          window.removeEventListener('scroll', measure);
        };
      }
    }
  }, [node, data]);

  return [ref, dimensions, node];
}

Parent

export default function Main(props: { notifications: Notification[] }) {
    const { notifications } = props;
    const [headHeight, setHeadHeight] = useState(0)

    const updateHeadHeight = () => {
        setHeadHeight(headHeight)
    }

    return (
         <main>
            <Header updateParent={updateHeadHeight}/>
           {headHeight}
        </main>
    )
}

Child

import { useDimensions } from '../../lib/design/measure';
import React, { useState, useLayoutEffect } from 'react';

export default function DefaultHeader(props, data) {
    const [
        ref,
        { height, width, top, left, x, y, right, bottom }
      ] = useDimensions(data);
    ;

    return <>
       <div ref={ref} className="header">
          <h1>Hello!</h1>
       </div>   
    </>
}
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Personally, I would call the hook in the Main component and wrap the child component in a forwardRef (check docs here).

See full example here:

Main.tsx

export default function Main(props: { notifications: Notification[] }) {
    const { notifications } = props;
    const [ref, dimensions] = useDimensions()

    return (
         <main>
            <Header ref={ref}/>
           {JSON.stringify(dimensions)}
        </main>
    )
}

What's done here, we just pass the ref down the tree to the child component and we just show the dimensions (testing purposes).

DefaultHeader.tsx

import { forwardRef } from "react";

const DefaultHeader = forwardRef((_, ref) => {
  return (
    <>
      <div ref={ref} className="header" >
        <h1>Hello!</h1>
      </div>
    </>
  );
});

export default DefaultHeader;

Here, we just attach the ref to the container that it has previously been (your example).

See full example on this CodeSandbox.

Let me know if you need more explanations on this.

about 4 years ago · Juan Pablo Isaza Relatório

0

You could just add a useEffect hook within the DefaultHeader component like this:

useEffect(() => props.updateParent(height), [props.updateParent, height])

This hook should run anytime it detects changes to the height variable or props.updateParent props. Just make sure you are declaring this hook after the useDimensions hook so it doesn't throw an undefined error.

about 4 years ago · Juan Pablo Isaza Relatório

0

You are seriously overcomplicating this by limiting yourself to the react way of doing things. You can simply use Event Bubbling to achieve what you want. All you need to do is dispatch a Custom Event event on the child element that will bubble up through each ancestor to the window. Then intercept this event in the parent element and react to it.

let m = document.querySelector('main');
let s = document.querySelector('section');
let b = document.querySelector('button');

b.addEventListener('click', event => {
  s.style.height = '200px';
});

m.addEventListener('resize', event => {
  console.log('new size:', event.detail);
});

new ResizeObserver(entries => {
  for (let e of entries) {
    s.dispatchEvent(
      new CustomEvent('resize', {
        detail: e.contentRect,
        bubbles: true
      })
    );
  }
}).observe(s);
main { background: green; padding: 1rem; margin-top: 1rem; }
section { background: orange; }
<button> Test </button>

<main>
  <section></section>
</main>

Just implement the ResizeObserver block in the child component and the resize Event Listener in the parent component.

This method achieves the desired effect in a decoupled and standards-compliant way. The child element is merely announcing the change to it's state (in the DOM, not React state). Any ancestor element can then act on this behavior as needed or ignore it. The parent element can also receive this resize event from any descendant element regardless of how deeply nested it may be. It also does not care which descendant element has changed. If you have multiple descendants that could change, this will trigger for any one of them.

Additionally, the resize event here is NOT tied to the window. ANY changes to the child element's size will trigger the event listener on the parent.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda