检测元件参考高度变化

问题描述 投票:0回答:6

是否可以检测元素引用何时改变其高度? 我尝试使用以下内容,但是当元素的高度由于某种原因发生变化时,不会检测到该变化。 (请考虑这也必须在 IE11 中工作)

useEffect(() => {
  // detect change in reference height
}, [elementRef])
reactjs react-hooks
6个回答
46
投票

我注意到另一个答案提到使用 ResizeObserver,但答案不完整,所以我想添加自己的答案。

使用useEffect

您可以在

ResizeObserver
钩子内创建一个
useEffect
,然后在元素更改大小时执行您想要执行的操作。记得在清理功能中断开与
resizeObserver
的连接。

useEffect(() => {
  if (!elementRef.current) return;
  const resizeObserver = new ResizeObserver(() => {
    // Do what you want to do when the size of the element changes
  });
  resizeObserver.observe(elementRef.current);
  return () => resizeObserver.disconnect(); // clean up 
}, []);

使用useCallback

正如评论中提到的,也可以使用

useCallback
代替
useEffect

您可以在

ResizeObserver
钩子内创建一个
useCallback
,然后在元素更改大小时执行您想要执行的操作。 React 有一个关于如何测量 DOM 节点的示例

const elementRef = useCallback(node => {
  if (!node) return;
  const resizeObserver = new ResizeObserver(() => { 
    // Do what you want to do when the size of the element changes
  });
  resizeObserver.observe(node);
}, []);

4
投票

最有效的方法是使用调整大小观察者

你可以在useEffect中设置它,并在组件卸载时清除它。


1
投票

你可以只使用

window

我下面的示例在组件卸载时使用清理

removeEventListener
功能进行了优化。

const BoxAndHeight = () => {
  const ref = React.useRef(null);
  const [height, setHeight] = React.useState(0);

  const onResize = React.useCallback(() => {
    if (ref.current) setHeight(ref.current.clientHeight);
  }, []);

  React.useEffect(() => {
    window.addEventListener("resize", onResize);
    onResize();
    return () => {
      window.removeEventListener("resize", onResize);
    };
  }, []);

  return (
    <div ref={ref} style={style}>
      <h1>My height: {height}</h1>
      <p>
        {dummyContent}
      </p>
    </div>
  );
}

// Render it
ReactDOM.createRoot(
    document.getElementById("root")
).render(<BoxAndHeight />);

const style = {
  border: "2px solid #ccc",
  padding: "10px",
  backgroundColor: "#eee"
};
const dummyContent = "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Distinctio, fugiat. Ex in neque velit perspiciatis recusandae, deleniti illum error ea distinctio obcaecati nisi deserunt ab unde corporis quas magnam quo cupiditate dolor dicta? Eos nostrum delectus suscipit! Hic corrupti, assumenda quo modi rem aperiam voluptas explicabo alias fuga error nulla. Eos tenetur voluptas repellat. Tempore, ab harum. Recusandae impedit adipisci soluta officia sunt quis voluptas, quae ea! Eveniet vero incidunt enim quod, voluptate fugiat maxime deserunt et laudantium quidem, ducimus sunt ratione voluptatem libero neque accusamus praesentium fugit doloremque est nisi excepturi. Quo inventore est soluta culpa quos? Minus, laudantium!";
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>


0
投票

我认为你可以在 useEffect 依赖项中使用

elementRef.current.clientHeight
来监听标签的高度。

我用这个案例进行了测试,它有效。

function App() {
  const tag = useRef();
  const [height, setHeight] = useState(10);
  useEffect(() => {
    console.log("updated", tag?.current?.clientHeight);
  }, [tag?.current?.clientHeight]);

  useEffect(() => {
    setInterval(() => {
      setHeight((height) => height + 10);
      console.log(height, tag.current.clientHeight);
    }, 2000);
  }, []);

  return (
    <div className="App" ref={tag}>
      <div style={{ height: height, backgroundColor: "green" }}></div>
    </div>
  );
}

这是codesandbox https://codesandbox.io/embed/reactjs-playground-forked-b8j5n?fontsize=14&hidenavigation=1&theme=dark


0
投票

在 React 中,使用诸如在

document.body.scrollHeight
上更新之类的东西对我有用:

const [viewHeight, setViewHeight] = useState<
  string | number
>("100vh")

useEffect(() => {
  setViewHeight(document.body.scrollHeight)
}, [document.body.scrollHeight])

...

return <div style={{ height: viewHeight }}>...</div>

-4
投票

可能的解决方案是使用 React Refs。尝试这个例子作为参考:

export default function Home() {
  const divRef = createRef()
  // ...
  return (
    <div style={{ height: '100vh', width: '100vw' }}>
      <div
        ref={divRef} // ...
      ></div>
    </div>
  )
}

详细代码这里.

© www.soinside.com 2019 - 2024. All rights reserved.