diff --git a/src/lib/teact/teact.ts b/src/lib/teact/teact.ts index f1760afaa..96407c72a 100644 --- a/src/lib/teact/teact.ts +++ b/src/lib/teact/teact.ts @@ -76,10 +76,16 @@ interface ComponentInstance { memos: { cursor: number; byCursor: { - current: any; + value: any; dependencies: any[]; }[]; }; + refs: { + cursor: number; + byCursor: { + current: any; + }[]; + }; }; prepareForFrame?: () => void; forceUpdate?: () => void; @@ -176,6 +182,10 @@ function createComponentInstance(Component: FC, props: Props, children: any[]): cursor: 0, byCursor: [], }, + refs: { + cursor: 0, + byCursor: [], + }, }, }; @@ -259,6 +269,7 @@ export function renderComponent(componentInstance: ComponentInstance) { componentInstance.hooks.state.cursor = 0; componentInstance.hooks.effects.cursor = 0; componentInstance.hooks.memos.cursor = 0; + componentInstance.hooks.refs.cursor = 0; const { Component, props } = componentInstance; let newRenderedValue; @@ -373,11 +384,6 @@ function unmountComponent(componentInstance: ComponentInstance) { return; } - // We need to clean refs before running effect cleanups - componentInstance.hooks.memos.byCursor.forEach((memoContainer) => { - memoContainer.current = undefined; - }); - componentInstance.hooks.effects.byCursor.forEach((effect) => { if (effect.cleanup) { try { @@ -410,9 +416,14 @@ function helpGc(componentInstance: ComponentInstance) { }); componentInstance.hooks.memos.byCursor.forEach((hook) => { + hook.value = undefined as any; hook.dependencies = undefined as any; }); + componentInstance.hooks.refs.byCursor.forEach((hook) => { + hook.current = undefined as any; + }); + componentInstance.hooks = undefined as any; componentInstance.$element = undefined as any; componentInstance.renderedValue = undefined; @@ -643,7 +654,7 @@ export function useLayoutEffect(effect: () => Function | void, dependencies?: re export function useMemo(resolver: () => T, dependencies: any[], debugKey?: string): T { const { cursor, byCursor } = renderingInstance.hooks.memos; - let { current } = byCursor[cursor] || {}; + let { value } = byCursor[cursor] || {}; if ( byCursor[cursor] === undefined @@ -659,17 +670,17 @@ export function useMemo(resolver: () => T, dependencies: any[], d ); } - current = resolver(); + value = resolver(); } byCursor[cursor] = { - current, + value, dependencies, }; renderingInstance.hooks.memos.cursor++; - return current; + return value; } export function useCallback(newCallback: F, dependencies: any[], debugKey?: string): F { @@ -682,10 +693,16 @@ export function useRef(): { current: T | undefined }; // TT way (empty is `un export function useRef(initial: null): { current: T | null }; // React way (empty is `null`) // eslint-disable-next-line no-null/no-null export function useRef(initial?: T | null) { - return useMemo(() => ({ - current: initial, - // eslint-disable-next-line react-hooks/exhaustive-deps - }), []); + const { cursor, byCursor } = renderingInstance.hooks.refs; + if (!byCursor[cursor]) { + byCursor[cursor] = { + current: initial, + }; + } + + renderingInstance.hooks.refs.cursor++; + + return byCursor[cursor]; } export function memo(Component: T, debugKey?: string) {