You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用React useRef Hook获取组件高度?按钮高度判断逻辑异常问题排查

React useRef 相关问题解答

Hey there! Let's break down your two questions about using React's useRef hook and the issue with your button loading component.

问题1:如何使用React的useRef Hook获取组件的高度?

To get a component's height with useRef, you need to follow a couple key steps—since refs don't populate until the component mounts, you can't just grab the height on initial render. Here's a straightforward approach:

  1. Create a ref with useRef and attach it to your target element.
  2. Use useEffect to access the ref after the component has mounted (this ensures the DOM element exists).
  3. Choose the right height property based on your needs:
    • clientHeight: Includes the element's content + padding, excludes borders, margins, and scrollbars.
    • offsetHeight: Includes content + padding + borders, and accounts for scrollbars if present.
    • scrollHeight: Measures the full height of the element's content (even parts hidden by overflow), excluding borders/margins.

Example Code:

import { useRef, useEffect } from 'react';

function MyComponent() {
  const elementRef = useRef(null);

  useEffect(() => {
    if (elementRef.current) {
      const componentHeight = elementRef.current.clientHeight;
      console.log('Component height:', componentHeight);
    }
  }, []); // Empty dependency array runs this only after initial mount

  return (
    <div ref={elementRef} style={{ height: '120px', padding: '1rem', border: '1px solid #ccc' }}>
      This is my component
    </div>
  );
}

问题2:为什么按钮高度为50px时仍显示SpinnerTwo组件?

Looking at your code, there are two main issues causing this unexpected behavior:

  1. Ref is null on initial render: When the component first renders, refButton.current hasn't been attached to the button element yet. So refButton.current?.clientHeight returns undefined, which doesn't equal 50—hence SpinnerTwo renders first.
  2. Ref changes don't trigger re-renders: Even after the ref attaches to the button, updating the ref doesn't cause the component to re-render. So your condition never gets re-evaluated with the actual height value.

Fix: Combine useRef with useState and useEffect

We'll use useState to store the button height (so changes trigger re-renders) and useEffect to fetch the height after mount (and listen for resizes if needed):

import { useRef, useEffect, useState } from 'react';
import styled from 'styled-components';

const Button = styled.button` height: 50px; `;

function ButtonLoading({ onClick }) {
  const refButton = useRef<HTMLButtonElement | null>(null);
  const [buttonHeight, setButtonHeight] = useState(0);

  useEffect(() => {
    const updateHeight = () => {
      if (refButton.current) {
        setButtonHeight(refButton.current.clientHeight);
      }
    };

    // Run once after mount to get initial height
    updateHeight();

    // Optional: Listen for window resizes if your button might change height responsively
    window.addEventListener('resize', updateHeight);

    // Clean up the event listener when component unmounts
    return () => window.removeEventListener('resize', updateHeight);
  }, []);

  return (
    <Button ref={refButton} onClick={onClick}>
      {buttonHeight === 50 ? <SpinnerOne /> : <SpinnerTwo />}
    </Button>
  );
}

Quick Note:

If you need the height immediately after DOM updates (before the browser paints), you can swap useEffect with useLayoutEffect—it runs synchronously after DOM mutations, which can be useful for layout-related calculations.

内容的提问来源于stack exchange,提问作者Rafael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 23:12:37