我有一个使用备忘录的简单反应组件,例如:
const Greeting = memo(function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
});
我如何衡量这份备忘录的成功程度?例如:我想知道它由于备忘录而跳过重新渲染的频率。是否有一个通用的钩子/实用程序可以用来测量这个?
我想知道所有尝试渲染的计数以及由于备忘录而跳过的渲染的计数。
也许有我自己的备忘录功能来计算这个?正在想这样的事情:
function memoProfile(Component, arePropsEqual) {
let allRenders = 0;
let skippedRenders = 0;
return memo(Component, (prevProps, nextProps) => {
allRenders++;
const propsEqual = arePropsEqual
? arePropsEqual(prevProps, nextProps)
: false; // TODO: use default memo comparison
if (propsEqual) {
skippedRenders++;
}
console.log(`Skipped renders: ${skippedRenders}/${allRenders} (${(skippedRenders / allRenders * 100).toFixed(2)}%)`);
return propsEqual;
});
}
不知道如何调用默认的备忘录比较,或者有更好的方法吗?
我如何衡量这份备忘录的成功程度?例如:我想知道如何 通常它会因为备忘录而跳过重新渲染。有通用的吗 我可以用来测量这个的目的钩子/实用程序?
不,没有任何“开箱即用”的东西可以衡量这一点。
一般来说,证明否定性也相当困难。证明组件在您期望时呈现比证明它在您不期望时未呈现更容易。
我想知道所有尝试渲染的计数和计数 由于备忘录而被跳过的渲染。
如果您只是想知道
memo
高阶组件在父子耦合之间的效果如何,您可以使用 React ref 来跟踪组件的渲染计数,并比较计数。
示例:
const renderCountRef = React.useRef(0);
React.useLayoutEffect(() => {
renderCountRef.current++;
});
这是一个父组件具有两种状态的演示,
count1
和count2
,其中count1
作为道具传递给子组件,并触发子组件重新渲染。您可以在这里观察到,子组件仅在其自身状态更新或从父组件传递的 prop 值发生更改时重新渲染。当父组件的 count2
状态更新并且父组件重新渲染时,观察子组件没有重新渲染。
const Child = (props) => {
const [count, setCount] = React.useState(0);
const renderCountRef = React.useRef(0);
React.useLayoutEffect(() => {
renderCountRef.current++;
});
return (
<React.Fragment>
<h2>Child</h2>
<div>
State: {count}{" "}
<button type="button" onClick={() => setCount((c) => c + 1)}>
+1
</button>{" "}
--- Renders: {renderCountRef.current}
</div>
<div>Parent State1: {props.state1}</div>
</React.Fragment>
);
};
const MemoizedChild = React.memo(Child);
const Parent = () => {
const [count1, setCount1] = React.useState(0);
const [count2, setCount2] = React.useState(0);
const renderCountRef = React.useRef(0);
React.useLayoutEffect(() => {
renderCountRef.current++;
});
return (
<div className="App">
<h2>Parent</h2>
<div>
State1: {count1}{" "}
<button type="button" onClick={() => setCount1((c) => c + 1)}>
+1
</button>{" "}
--- State2: {count2}{" "}
<button type="button" onClick={() => setCount2((c) => c + 1)}>
+1
</button>{" "}
--- Renders: {renderCountRef.current}
</div>
<hr />
<MemoizedChild state1={count1} />
</div>
);
};
const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<Parent />
</React.StrictMode>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<div id="root" />