首页 > 解决方案 > 反应:使div的宽度等于高度。高度计算不正确

问题描述

这个项目的 Github 仓库


基于我看到的其他解决方案,我创建了一个组件,该组件应该计算其子项的宽度和高度,然后将宽度和高度设置为等于其中较长者的长度.

    import React, {useState, useEffect, useRef} from 'react';
    
    const SymmetricalDiv = ({style, children, ...props}) => {
        const [diamStyle, setDiamStyle] = useState({});
        const elementRef = useRef(null);
        style = style ? Object.assign({}, diamStyle, style) : diamStyle ;
    
        useEffect(() => {
            const width = elementRef.current.clientWidth;
            const height = elementRef.current.clientHeight;
            const diam = Math.max(width, height);   
            setDiamStyle({width: diam, height: diam});
        }, []);
    
        return (
            <div ref={elementRef} {...props} style={style}>
                {children}
            </div>
        );
    };


这是我尝试使用此组件的示例。(样式是使用引导程序完成的)

    import React from 'react';
    import {SymmetricalDiv} from 'components/Styled'
    import svgLogo from 'src/SVG_logo.svg'

    const MyComponent = () => {
        return (
            <SymmetricalDiv className='rounded-circle d-flex flex-column align-items-center bg-danger'>
                <strong >A title</strong>
                <span>A description</span>
                <img className='my-3' src={svgLogo} />
                <a href="#">A Link</a>
            </SymmetricalDiv>
        );
    };

此示例产生以下结果。它计算的高度不正确,并决定宽度是较长的维度。然后将宽度和高度设置为等于宽度,这就是为什么一些孩子出现在圆圈之外的原因。

在此处输入图像描述

标签: javascriptreactjstwitter-bootstrapreact-hooksuse-ref

解决方案


它与高度/宽度不匹配的原因似乎是因为您的图像没有设置高度/宽度。

没有设置高度/宽度的图像最初以 0 宽度/高度开始,这是您进行计算的地方。然后加载图像并进行回流。

有两种简单的方法可以解决您的问题:

设置图像的宽度

这可以确保图像在完全加载之前知道它的高度/宽度。

<SymmetricalDiv className="rounded-circle d-flex flex-column align-items-center bg-danger">
  <strong>A title</strong>
  <span>A description</span>
  <img className="my-3" width="168px" height="150px" src={svgLogo} />
  <a href="#">A Link</a>
</SymmetricalDiv>

内联 SVG/使其成为组件

这完全消除了图像的加载步骤。

// SVGLogo.js

export default () => {
  return <svg>...</svg>
}
// App.js

<SymmetricalDiv className="rounded-circle d-flex flex-column align-items-center bg-warning">
  <strong>A title</strong>
  <span>A description</span>
  <SVGLogo />
  <a href="#">A Link</a>
</SymmetricalDiv>

您可以在此代码沙盒示例中看到这两种实现的实际效果

明确图像的大小对于确保您的应用程序按预期运行非常有帮助。

您还可以阅读有关防止由于图像加载而导致回流的更多信息


推荐阅读