import React, { useState, useRef, useEffect } from "react";
import ResizeObserver from "resize-observer-polyfill";
export function useMeasure() {
const ref = useRef();
const [bounds, set] = useState({ left: 0, top: 0, width: 0, height: 0 });
const [ro] = useState(
() => new ResizeObserver(([entry]) => set(entry.contentRect))
);
useEffect(() => {
if (ref.current) ro.observe(ref.current);
return () => ro.disconnect();
}, []);
return [{ ref }, bounds];
}
function App() {
const [size, setSize] = useState(100);
const Change = () => {
setSize(300);
};
const [bind, { height: viewHeight }] = useMeasure();
console.log(bind);
return (
<div
style={{
background: "blue",
width: 200,
height: size
transition: "height 1s ease-out"
}}
{...bind}
onClick={Change}
/>
);
}
export default App;
加了 transition: "height 1s ease-out" 这条动画过渡属性后,有了动画,但是貌似这个函数组件也执行了很多次:
如图,console.log(bind);这条语句执行很多次,意味着这个函数组件也执行了这么多次,去掉这个动画后,就变成了正常的两次?
求解?这是react的正常表现?还是说有问题的吧?有问题的话,原因?怎么优化呢?
问题好像知道了,因为是useMeasure大致原理就是对dom的属性用ResizeObserver api 存在state里,由于ResizeObserver的不断监听,存入的dom属性state也就不断变化了,但这样导致react在动画变换的过程中不断地reRender,就导致了外面的App组件也不断执行了。我理解的是这样。