我正在学习React,遇到了以下情况:我有几个组件的行为取决于容器的大小。当然,我希望一切都是响应的,所以我需要动态地获取大小。我是这样做的:
import React, { useEffect, useState, useRef } from "react";
const ComponentOne = () => {
const refContainer = useRef();
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
const handleSize = () => {
setDimensions({
width: refContainer.current.offsetWidth,
height: refContainer.current.offsetHeight,
});
};
/* Run first time */
useEffect(() => {
handleSize();
}, []);
/* Run on resize */
useEffect(() => {
window.addEventListener("resize", handleSize);
}, []);
/* Some useful code which depends on those dimensions here
.....
*/
return (
<>
<div ref={refContainer}>Something produced by that useful code</div>
</>
);
};
export default ComponentOne;
一切正常。现在,假设我需要5个这样的分量。我有一种方法有一些辅助函数/模块,容器名称作为参数,返回该容器的尺寸?
注。就重用代码而言,hoc工作得很好。我不能把它应用到我的情况下,不能使用ref
属性从我的组件在HOC中,也不能把它从HOC传递到组件。同时,我在一个外部库react-cool-dimensions
中找到了一个很好的一行代码:
const { observe, width, height } = useDimensions();
,设置ref={observe}
。组件本身不需要钩子,加载和调整大小事件在useDimensions
函数中捕获。
这似乎是一个高阶组件的完美用例。
我还没有测试过这个,所以你可能需要调整它来让它工作;但是下面的代码创建了一个更高阶的组件来包装您的组件。只要你的组件有一个width
和一个height
道具,它应该自动填充它们。
export const withDimensions = (
component,
componentName = component.displayName ?? component.name
) => {
const WithDimensions = (props) => {
const refContainer = useRef();
const [dimensions, setDimensions] = useState({
width: 0,
height: 0,
});
const handleSize = () => {
setDimensions({
width: refContainer.current?.offsetWidth ?? 0,
height: refContainer.current?.offsetHeight ?? 0,
});
};
useEffect(() => {
handleSize();
}, []);
useEffect(() => {
window.addEventListener("resize", handleSize);
}, []);
return component({ ...props, ...dimensions, ref: refContainer });
};
WithDimensions.displayName = `withSampleHoC(${componentName})`;
return WithDimensions;
};