11 reactjs
我有一个useRef
附加到一个div。当 div 的宽度发生变化时,我需要更新我的 UI。我可以使用 访问它ref.current.innerWidth
,但是,当它的宽度发生变化时,它不会更新依赖于 的其他元素ref.current.innerWidth
。
我怎样才能做到这一点?
代码:
let ref = useRef();
return (
<>
<Box resizable ref={ref}>
This is a resizable div
</Box>
<Box width={ref.current.innerWidth}>
This box needs the same with as the resizable div
</Box>
</>
);
Run Code Online (Sandbox Code Playgroud)
fre*_*edy 11
您可以使用 ResizeObserver。像这样实现,每次 ref 的大小发生变化时,它都会设置宽度:
let ref = useRef()
const [width, setwidth] = useState(0)
useEffect(() => {
const observer = new ResizeObserver(entries => {
setwidth(entries[0].contentRect.width)
})
observer.observe(ref.current)
return () => ref.current && observer.unobserve(ref.current)
}, [])
return (
<>
<Box ref={ref}>
This is a resizable div
</Box>
<Box width={width}>
This box needs the same with as the resizable div
</Box>
</>
)
Run Code Online (Sandbox Code Playgroud)
对于任何寻求可重用逻辑和Typescript支持的人,我根据@fredy的精彩答案创建了以下自定义挂钩,并修复了我在他的答案中发现的一些问题:
import { useState, useRef, useEffect } from "react";
export const useObserveElementWidth = <T extends HTMLElement>() => {
const [width, setWidth] = useState(0);
const ref = useRef<T>(null);
useEffect(() => {
const observer = new ResizeObserver((entries) => {
setWidth(entries[0].contentRect.width);
});
if (ref.current) {
observer.observe(ref.current);
}
return () => {
ref.current && observer.unobserve(ref.current);
};
}, []);
return {
width,
ref
};
};
Run Code Online (Sandbox Code Playgroud)
然后,导入useObserveElementWidth
并使用它,如下所示:
const YourComponent = () => {
const { width, ref } = useObserveElementWidth<HTMLDivElement>();
return (
<>
<Box resizable ref={ref}>
This is a resizable div
</Box>
<Box width={width}>
This box needs the same with as the resizable div
</Box>
</>
);
};
Run Code Online (Sandbox Code Playgroud)
我为它创建了一个示例codesandbox。
您应该使用 useEffect 和 useState 以及窗口上的事件监听器创建生命周期来监听数据更改,然后基于该更改重新渲染组件。
const [size, setSize] = useState(null);
let ref = useRef();
const updateDimensions = () => {
console.log(ref.current.clientWidth);
if (ref.current) setSize(ref.current.clientWidth);
};
useEffect(() => {
window.addEventListener("resize", updateDimensions);
setSize(ref.current.clientWidth);
return () => {
console.log("dismount");
window.removeEventListener("resize", updateDimensions);
};
}, []);
return (
<>
<div ref={ref}>This is a resizable div</div>
<div
style={{
width: size,
border: "1px solid"
}}
>
This div needs the same with as the resizable div
</div>
</>
);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8078 次 |
最近记录: |