React:使 div 的宽度等于高度。高度计算不正确
React: Making width of div equal to height. The height is not being calculated correctly
基于我看到的解决此问题的其他解决方案,我创建了一个组件,该组件应该计算其 children 的宽度和高度,然后将宽度和高度设置为等于长者的长度。
- 例如果width=30,height=20,那么宽和高应该设置为30,如果height是30,结果应该是一样的,宽度为 20.
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>
);
};
这是我尝试使用此组件的示例。 (样式是使用 bootstap 完成的)
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>
);
};
此示例生成以下结果。是高度计算错误,把宽度确定为较长的尺寸。然后它将宽度和高度设置为 等于宽度 ,这就是为什么一些 children 出现在圆圈之外的原因。
它与 height/width 不匹配的原因似乎是因为您的图片没有设置 height/width。
没有设置 heights/widths 的图像最初从 0 width/height 开始,这是您进行计算的地方。然后加载图像并发生回流。
有两种简单的方法可以解决您的问题:
设置图片的宽度
这可以确保图像在完全加载之前知道它的 height/width。
<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/Make 它是一个组件
这完全删除了图像的加载步骤。
// 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>
您可以在此 Code Sandbox example
中看到两种实现的实际效果
明确说明图像的大小对于确保您的应用按预期运行非常有帮助。
您还可以阅读更多关于 preventing reflow due to image loading
基于我看到的解决此问题的其他解决方案,我创建了一个组件,该组件应该计算其 children 的宽度和高度,然后将宽度和高度设置为等于长者的长度。
- 例如果width=30,height=20,那么宽和高应该设置为30,如果height是30,结果应该是一样的,宽度为 20.
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>
);
};
这是我尝试使用此组件的示例。 (样式是使用 bootstap 完成的)
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>
);
};
此示例生成以下结果。是高度计算错误,把宽度确定为较长的尺寸。然后它将宽度和高度设置为 等于宽度 ,这就是为什么一些 children 出现在圆圈之外的原因。
它与 height/width 不匹配的原因似乎是因为您的图片没有设置 height/width。
没有设置 heights/widths 的图像最初从 0 width/height 开始,这是您进行计算的地方。然后加载图像并发生回流。
有两种简单的方法可以解决您的问题:
设置图片的宽度
这可以确保图像在完全加载之前知道它的 height/width。
<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/Make 它是一个组件
这完全删除了图像的加载步骤。
// 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>
您可以在此 Code Sandbox example
中看到两种实现的实际效果明确说明图像的大小对于确保您的应用按预期运行非常有帮助。
您还可以阅读更多关于 preventing reflow due to image loading