mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[runtime] useRenderCounter
---
(`react-forget-runtime` package seems to be synced to -.)
RFC: useRenderCounter hook:
- tracks # renders (increments on render path)
- exposes a global renderCounterRegistry (counting # renders in alive / mounted
components)
Next PR will modify BabelPlugin to add codegen
```js
// Similar to how we're currently importing `isForgetEnabled`
import {isInstrumentForgetEnabled_Secret} from "ReactForgetFeatureFlag";
// ...
function Component_uncompiled(props) {
if (isInstrumentForgetEnabled_Secret) {
useRenderCounter();
}
// ...
}
function Component_forget(props) {
if (isInstrumentForgetEnabled_Secret) {
useRenderCounter();
}
// ...
}
```
This commit is contained in:
@@ -12,6 +12,7 @@ const {
|
||||
ReactCurrentDispatcher,
|
||||
},
|
||||
useRef,
|
||||
useEffect,
|
||||
} = React;
|
||||
|
||||
export const $empty = Symbol.for("react.memo_cache_sentinel");
|
||||
@@ -89,3 +90,54 @@ export function $reset($) {
|
||||
export function $makeReadOnly() {
|
||||
throw new Error("TODO: implement $makeReadOnly in react-forget-runtime");
|
||||
}
|
||||
|
||||
/**
|
||||
* Instrumentation to count rerenders in React components
|
||||
*/
|
||||
export const renderCounterRegistry /*: Map<string,Set<{count: number}>>*/ =
|
||||
new Map();
|
||||
export function clearRenderCounterRegistry() {
|
||||
for (const counters of renderCounterRegistry.values()) {
|
||||
counters.forEach((counter) => {
|
||||
counter.count = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerRenderCounter(name, val) {
|
||||
let counters = renderCounterRegistry.get(name);
|
||||
if (counters == null) {
|
||||
counters = new Set();
|
||||
renderCounterRegistry.set(name, counters);
|
||||
}
|
||||
counters.add(val);
|
||||
}
|
||||
|
||||
function removeRenderCounter(name, val): void {
|
||||
const counters = renderCounterRegistry.get(name);
|
||||
if (counters == null) {
|
||||
return;
|
||||
}
|
||||
counters.delete(val);
|
||||
}
|
||||
|
||||
export function useRenderCounter(name): void {
|
||||
const val = useRef(null);
|
||||
|
||||
if (val.current != null) {
|
||||
val.current.count += 1;
|
||||
}
|
||||
useEffect(() => {
|
||||
// Not counting initial render shouldn't be a problem
|
||||
if (val.current == null) {
|
||||
const counter = { count: 0 };
|
||||
registerRenderCounter(name, counter);
|
||||
val.current = counter;
|
||||
}
|
||||
return () => {
|
||||
if (val.current !== null) {
|
||||
removeRenderCounter(name, val.current);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user