Teact: Fix updating ref when re-using DOM nodes

This commit is contained in:
Alexander Zinchuk 2023-06-16 12:44:44 +02:00
parent a582c20ebb
commit bab53d42ec
3 changed files with 35 additions and 3 deletions

View File

@ -16,6 +16,8 @@ import { addActiveTabChangeListener } from '../util/activeTabMonitor';
import { hasStoredSession } from '../util/sessions';
import buildClassName from '../util/buildClassName';
import { parseInitialLocationHash } from '../util/routing';
import { setupBeforeInstallPrompt } from '../util/installPrompt';
import useFlag from '../hooks/useFlag';
import usePrevious from '../hooks/usePrevious';
import useAppLayout from '../hooks/useAppLayout';
@ -26,10 +28,9 @@ import LockScreen from './main/LockScreen.async';
import AppInactive from './main/AppInactive';
import Transition from './ui/Transition';
import UiLoader from './common/UiLoader';
// import Test from './components/test/TestNoRedundancy';
// import Test from './test/TestUpdateRef';
import styles from './App.module.scss';
import { setupBeforeInstallPrompt } from '../util/installPrompt';
type StateProps = {
authState: GlobalState['authState'];

View File

@ -0,0 +1,25 @@
import React, { useEffect, useRef, useState } from '../../lib/teact/teact';
function TestUpdateRef() {
const [isShown, setIsShown] = useState(true);
// eslint-disable-next-line no-null/no-null
const shownRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// Input content should preserve, but ref should clean up
// eslint-disable-next-line no-console
console.log('!!!', shownRef.current);
}, [isShown]);
return (
<div onClick={() => setIsShown(!isShown)}>
{isShown ? (
<input ref={shownRef} />
) : (
<input />
)}
</div>
);
}
export default TestUpdateRef;

View File

@ -173,7 +173,13 @@ function renderWithVirtual<T extends VirtualElement | undefined>(
if (isTag) {
const $newAsTag = $new as VirtualElementTag;
$newAsTag.props.ref = $current.props.ref;
if ($current.props.ref?.current === currentTarget) {
$current.props.ref.current = undefined;
}
if ($newAsTag.props.ref) {
$newAsTag.props.ref.current = currentTarget;
}
if (nextSibling || options.forceMoveToEnd) {
insertBefore(parentEl, currentTarget, nextSibling);