Skip to content

Commit fc3c356

Browse files
committed
fix: Auto lock logic
1 parent b2f9261 commit fc3c356

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

src/useScrollLocker.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import * as React from 'react';
22
import { updateCSS, removeCSS } from 'rc-util/lib/Dom/dynamicCSS';
3+
import useLayoutEffect, {
4+
useLayoutUpdateEffect,
5+
} from 'rc-util/lib/hooks/useLayoutEffect';
36
import getScrollBarSize from 'rc-util/lib/getScrollBarSize';
47

58
let lockCount = 0;
@@ -9,6 +12,7 @@ const UNIQUE_ID = `rc-util-locker-${Date.now()}`;
912

1013
function syncLocker() {
1114
const nextLocked = lockCount > 0;
15+
1216
if (locked !== nextLocked) {
1317
locked = nextLocked;
1418

@@ -29,20 +33,31 @@ html body {
2933
}
3034

3135
export default function useScrollLocker(lock?: boolean) {
32-
React.useLayoutEffect(() => {
33-
if (lock) {
36+
const mergedLock = !!lock;
37+
38+
// Init only check lock
39+
useLayoutEffect(() => {
40+
if (mergedLock) {
41+
lockCount += 1;
42+
syncLocker();
43+
}
44+
}, []);
45+
46+
// Update will both check the lock state
47+
useLayoutUpdateEffect(() => {
48+
if (mergedLock) {
3449
lockCount += 1;
3550
syncLocker();
3651
} else {
3752
lockCount -= 1;
3853
syncLocker();
3954
}
40-
}, [lock]);
55+
}, [mergedLock]);
4156

42-
const lockRef = React.useRef(lock);
43-
lockRef.current = lock;
57+
const lockRef = React.useRef(mergedLock);
58+
lockRef.current = mergedLock;
4459

45-
React.useLayoutEffect(() => {
60+
useLayoutEffect(() => {
4661
return () => {
4762
if (lockRef.current) {
4863
lockCount -= 1;

tests/index.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,40 @@ describe('Portal', () => {
6868
expect(renderTimes).toEqual(1);
6969
});
7070
});
71+
72+
describe('dynamic change autoLock', () => {
73+
function test(name: string, config?: Parameters<typeof render>[1]) {
74+
it(name, () => {
75+
const { rerender } = render(<Portal open />, config);
76+
expect(document.body).not.toHaveStyle({
77+
overflowY: 'hidden',
78+
});
79+
80+
rerender(<Portal open autoLock />);
81+
expect(document.body).toHaveStyle({
82+
overflowY: 'hidden',
83+
});
84+
85+
rerender(<Portal open={false} autoLock />);
86+
expect(document.body).not.toHaveStyle({
87+
overflowY: 'hidden',
88+
});
89+
90+
rerender(<Portal open autoLock />);
91+
expect(document.body).toHaveStyle({
92+
overflowY: 'hidden',
93+
});
94+
95+
rerender(<Portal open autoLock={false} />);
96+
expect(document.body).not.toHaveStyle({
97+
overflowY: 'hidden',
98+
});
99+
});
100+
}
101+
102+
test('basic');
103+
test('StrictMode', {
104+
wrapper: React.StrictMode,
105+
});
106+
});
71107
});

0 commit comments

Comments
 (0)