Skip to content

Commit

Permalink
fix: useScrollLockController rm useEffect (#8213)
Browse files Browse the repository at this point in the history
  • Loading branch information
SevereCloud authored Jan 30, 2025
1 parent 7909633 commit 0e0e2a7
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 26 deletions.
48 changes: 42 additions & 6 deletions packages/vkui/src/components/AppRoot/ScrollContext.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ describe(useScrollLock, () => {
</GlobalScrollController>
),
});

h.rerender(false);
h.rerender();

expect(beforeScrollLockFn).toHaveBeenCalled();

expect(getStyleAttributeObject(document.body)).toEqual({
Expand All @@ -71,6 +75,32 @@ describe(useScrollLock, () => {
clearWindowMeasuresMock();
});

test('unmount check', () => {
const h = renderHook(useScrollLock, {
wrapper: ({ children }) => (
<GlobalScrollController elRef={createRef<HTMLElement>()}>
{children}
</GlobalScrollController>
),
});

expect(getStyleAttributeObject(document.body)).toEqual({
'position': 'fixed',
'top': `-${0}px`,
'left': `-${0}px`,
'right': '0px',
'overflow-x': 'scroll',
'overflow-y': 'scroll',
});
expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.body)).toBe('none');
expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.documentElement)).toBe('none'); // prettier-ignore

h.unmount();
expect(getStyleAttributeObject(document.body)).toEqual({});
expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.body)).toBe('');
expect(jestWorkaroundGetOverscrollBehaviorPropertyValue(document.documentElement)).toBe('');
});

test('context api', () => {
const contextRef = createRef<ScrollContextInterface>();
render(
Expand Down Expand Up @@ -110,13 +140,19 @@ describe(useScrollLock, () => {

const beforeScrollLockFn = jest.fn();
const h = renderHook(useScrollLock, {
wrapper: ({ children }) => (
<ElementScrollController elRef={elRef}>
{children}
<ChildWithContext beforeScrollLockFn={beforeScrollLockFn} />
</ElementScrollController>
),
wrapper: ({ children }) => {
return (
<ElementScrollController elRef={elRef}>
{children}
<ChildWithContext beforeScrollLockFn={beforeScrollLockFn} />
</ElementScrollController>
);
},
});

h.rerender(false);
h.rerender();

expect(beforeScrollLockFn).toHaveBeenCalled();

expect(getStyleAttributeObject(elRef.current)).toEqual({
Expand Down
37 changes: 17 additions & 20 deletions packages/vkui/src/components/AppRoot/ScrollContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import * as React from 'react';
import { noop } from '@vkontakte/vkjs';
import { clamp } from '../../helpers/math';
import { useCounter } from '../../hooks/useCounter';
import { useDOM } from '../../lib/dom';
import type { HasChildren } from '../../types';

Expand Down Expand Up @@ -61,29 +60,27 @@ export const useScroll = (): ScrollContextInterface => React.useContext(ScrollCo
* Если счетчик больше нуля, требуется заблокировать прокрутку
*/
function useScrollLockController(enableScrollLock: () => void, disableScrollLock: () => void) {
const isFirstEffect = React.useRef(true);
const [count, { increment: incrementScrollLockCounter, decrement: decrementScrollLockCounter }] =
useCounter(0);
const countRef = React.useRef(0);

const needLockScroll = count > 0;

React.useEffect(() => {
if (isFirstEffect.current) {
isFirstEffect.current = false;
return;
}

if (needLockScroll) {
const updateScrollLock = React.useCallback(() => {
if (countRef.current > 0) {
enableScrollLock();
} else {
disableScrollLock();
}
}, [needLockScroll, enableScrollLock, disableScrollLock]);
}, [enableScrollLock, disableScrollLock]);

const incrementScrollLockCounter = React.useCallback(() => {
countRef.current += 1;
updateScrollLock();
}, [updateScrollLock]);

const decrementScrollLockCounter = React.useCallback(() => {
countRef.current -= 1;
updateScrollLock();
}, [updateScrollLock]);

return {
incrementScrollLockCounter,
decrementScrollLockCounter,
};
return [incrementScrollLockCounter, decrementScrollLockCounter];
}

export interface ScrollControllerProps extends HasChildren {
Expand Down Expand Up @@ -145,7 +142,7 @@ export const GlobalScrollController = ({ children }: ScrollControllerProps): Rea
window!.scrollTo(-parseInt(scrollX || '0'), -parseInt(scrollY || '0'));
}, [document, window]);

const { incrementScrollLockCounter, decrementScrollLockCounter } = useScrollLockController(
const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController(
enableScrollLock,
disableScrollLock,
);
Expand Down Expand Up @@ -226,7 +223,7 @@ export const ElementScrollController = ({
el.scrollTo(-parseInt(scrollX || '0'), -parseInt(scrollY || '0'));
}, [elRef]);

const { incrementScrollLockCounter, decrementScrollLockCounter } = useScrollLockController(
const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController(
enableScrollLock,
disableScrollLock,
);
Expand Down

0 comments on commit 0e0e2a7

Please sign in to comment.