[Debug] Some more debug tools
This commit is contained in:
parent
3ac7711f17
commit
a17240466a
@ -3,12 +3,15 @@ import {
|
|||||||
fastRaf, onTickEnd, throttleWithPrimaryRaf, throttleWithRaf,
|
fastRaf, onTickEnd, throttleWithPrimaryRaf, throttleWithRaf,
|
||||||
} from '../../util/schedulers';
|
} from '../../util/schedulers';
|
||||||
import { flatten, orderBy } from '../../util/iteratees';
|
import { flatten, orderBy } from '../../util/iteratees';
|
||||||
import arePropsShallowEqual from '../../util/arePropsShallowEqual';
|
import arePropsShallowEqual, { getUnequalProps } from '../../util/arePropsShallowEqual';
|
||||||
import { handleError } from '../../util/handleError';
|
import { handleError } from '../../util/handleError';
|
||||||
import { removeAllDelegatedListeners } from './dom-events';
|
import { removeAllDelegatedListeners } from './dom-events';
|
||||||
|
|
||||||
export type Props = AnyLiteral;
|
export type Props = AnyLiteral;
|
||||||
export type FC<P extends Props = any> = (props: P) => any;
|
export type FC<P extends Props = any> = (props: P) => any;
|
||||||
|
export type FC_withDebug = FC & {
|
||||||
|
DEBUG_contentComponentName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export enum VirtualElementTypesEnum {
|
export enum VirtualElementTypesEnum {
|
||||||
Empty,
|
Empty,
|
||||||
@ -444,6 +447,10 @@ export function useState<T>(initial?: T): [T, StateHookSetter<T>] {
|
|||||||
value: initial,
|
value: initial,
|
||||||
nextValue: initial,
|
nextValue: initial,
|
||||||
setter: ((componentInstance) => (newValue: ((current: T) => T) | T) => {
|
setter: ((componentInstance) => (newValue: ((current: T) => T) | T) => {
|
||||||
|
if (!componentInstance.isMounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (byCursor[cursor].nextValue !== newValue) {
|
if (byCursor[cursor].nextValue !== newValue) {
|
||||||
byCursor[cursor].nextValue = typeof newValue === 'function'
|
byCursor[cursor].nextValue = typeof newValue === 'function'
|
||||||
? (newValue as (current: T) => T)(byCursor[cursor].value)
|
? (newValue as (current: T) => T)(byCursor[cursor].value)
|
||||||
@ -454,6 +461,20 @@ export function useState<T>(initial?: T): [T, StateHookSetter<T>] {
|
|||||||
componentInstance.forceUpdate = throttleWithRaf(() => forceUpdateComponent(componentInstance));
|
componentInstance.forceUpdate = throttleWithRaf(() => forceUpdateComponent(componentInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DEBUG_MORE) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(
|
||||||
|
'[Teact.useState]',
|
||||||
|
componentInstance.name,
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
(componentInstance.Component as FC_withDebug).DEBUG_contentComponentName
|
||||||
|
? `> ${(componentInstance.Component as FC_withDebug).DEBUG_contentComponentName}`
|
||||||
|
: '',
|
||||||
|
`Forced update at cursor #${cursor}, next value: `,
|
||||||
|
byCursor[cursor].nextValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
componentInstance.scheduleNextState();
|
componentInstance.scheduleNextState();
|
||||||
componentInstance.forceUpdate();
|
componentInstance.forceUpdate();
|
||||||
}
|
}
|
||||||
@ -556,13 +577,21 @@ export function useRef<T>(initial?: T | null) {
|
|||||||
}), []);
|
}), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function memo<T extends FC>(Component: T, areEqual = arePropsShallowEqual) {
|
export function memo<T extends FC>(Component: T, areEqual = arePropsShallowEqual, withDebug = false) {
|
||||||
return function TeactMemoWrapper(props: Props) {
|
return function TeactMemoWrapper(props: Props) {
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
const propsRef = useRef(props);
|
const propsRef = useRef(props);
|
||||||
const renderedRef = useRef();
|
const renderedRef = useRef();
|
||||||
|
|
||||||
if (!renderedRef.current || (propsRef.current && !areEqual(propsRef.current, props))) {
|
if (!renderedRef.current || (propsRef.current && !areEqual(propsRef.current, props))) {
|
||||||
|
if (DEBUG && withDebug) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(
|
||||||
|
`[Teact.memo] ${Component.name}: Update is caused by:`,
|
||||||
|
getUnequalProps(propsRef.current!, props).join(', '),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
propsRef.current = props;
|
propsRef.current = props;
|
||||||
renderedRef.current = createElement(Component, props) as VirtualElementComponent;
|
renderedRef.current = createElement(Component, props) as VirtualElementComponent;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, Props, useEffect, useState,
|
FC, FC_withDebug, Props, useEffect, useState,
|
||||||
} from './teact';
|
} from './teact';
|
||||||
|
|
||||||
import { DEBUG, DEBUG_MORE } from '../../config';
|
import { DEBUG, DEBUG_MORE } from '../../config';
|
||||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||||
import generateIdFor from '../../util/generateIdFor';
|
import generateIdFor from '../../util/generateIdFor';
|
||||||
import { throttleWithRaf } from '../../util/schedulers';
|
import { throttleWithRaf } from '../../util/schedulers';
|
||||||
import arePropsShallowEqual from '../../util/arePropsShallowEqual';
|
import arePropsShallowEqual, { getUnequalProps } from '../../util/arePropsShallowEqual';
|
||||||
import { orderBy } from '../../util/iteratees';
|
import { orderBy } from '../../util/iteratees';
|
||||||
import { GlobalState, GlobalActions, ActionTypes } from '../../global/types';
|
import { GlobalState, GlobalActions, ActionTypes } from '../../global/types';
|
||||||
import { handleError } from '../../util/handleError';
|
import { handleError } from '../../util/handleError';
|
||||||
@ -164,6 +164,8 @@ export function withGlobal<OwnProps>(
|
|||||||
) {
|
) {
|
||||||
return (Component: FC) => {
|
return (Component: FC) => {
|
||||||
return function TeactNContainer(props: OwnProps) {
|
return function TeactNContainer(props: OwnProps) {
|
||||||
|
(TeactNContainer as FC_withDebug).DEBUG_contentComponentName = Component.name;
|
||||||
|
|
||||||
const [id] = useState(generateIdFor(containers));
|
const [id] = useState(generateIdFor(containers));
|
||||||
const forceUpdate = useForceUpdate();
|
const forceUpdate = useForceUpdate();
|
||||||
|
|
||||||
@ -211,18 +213,6 @@ export function withGlobal<OwnProps>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUnequalProps(currentProps: AnyLiteral, newProps: AnyLiteral) {
|
|
||||||
const currentKeys = Object.keys(currentProps);
|
|
||||||
const currentKeysLength = currentKeys.length;
|
|
||||||
const newKeysLength = Object.keys(newProps).length;
|
|
||||||
|
|
||||||
if (currentKeysLength !== newKeysLength) {
|
|
||||||
return ['LENGTH'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentKeys.filter((prop) => currentProps[prop] !== newProps[prop]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
(window as any).getGlobal = getGlobal;
|
(window as any).getGlobal = getGlobal;
|
||||||
|
|
||||||
|
|||||||
@ -24,3 +24,15 @@ export default function arePropsShallowEqual(currentProps: AnyLiteral, newProps:
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getUnequalProps(currentProps: AnyLiteral, newProps: AnyLiteral) {
|
||||||
|
const currentKeys = Object.keys(currentProps);
|
||||||
|
const currentKeysLength = currentKeys.length;
|
||||||
|
const newKeysLength = Object.keys(newProps).length;
|
||||||
|
|
||||||
|
if (currentKeysLength !== newKeysLength) {
|
||||||
|
return ['%LENGTH%'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentKeys.filter((prop) => currentProps[prop] !== newProps[prop]);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user