From 6ddcc8b725870f6ca34178aa250d6237caa09910 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 18:37:44 +0800 Subject: [PATCH 1/8] fix: backtop & menu lint, code simplification, deprecated pageYOffset removed --- src/packages/backtop/backtop.taro.tsx | 27 +++----- src/packages/backtop/backtop.tsx | 97 ++++++++++++--------------- src/packages/menu/menu.taro.tsx | 34 +++++----- src/packages/menu/menu.tsx | 33 ++++----- 4 files changed, 84 insertions(+), 107 deletions(-) diff --git a/src/packages/backtop/backtop.taro.tsx b/src/packages/backtop/backtop.taro.tsx index a6ba3f6ac6..ceea9313c6 100644 --- a/src/packages/backtop/backtop.taro.tsx +++ b/src/packages/backtop/backtop.taro.tsx @@ -28,17 +28,20 @@ export const BackTop: FunctionComponent< ...defaultProps, ...props, } - const classPrefix = 'nut-backtop' - const [backTop, SetBackTop] = useState(false) - + const cls = classNames( + classPrefix, + { + show: backTop, + }, + className + ) // 监听用户滑动页面事件 usePageScroll((res) => { const { scrollTop } = res scrollTop >= threshold ? SetBackTop(true) : SetBackTop(false) }) - // 返回顶部点击事件 const goTop = (e: MouseEvent) => { onClick && onClick(e) @@ -47,7 +50,6 @@ export const BackTop: FunctionComponent< duration: duration > 0 ? duration : 0, }) } - const styles = Object.keys(style || {}).length !== 0 ? { @@ -59,21 +61,8 @@ export const BackTop: FunctionComponent< bottom: '20px', zIndex, } - return ( -
{ - goTop(e) - }} - > +
goTop(e)}> {children || }
) diff --git a/src/packages/backtop/backtop.tsx b/src/packages/backtop/backtop.tsx index 4366b2fab4..dd5eab5466 100644 --- a/src/packages/backtop/backtop.tsx +++ b/src/packages/backtop/backtop.tsx @@ -1,13 +1,17 @@ -import React, { FunctionComponent, useEffect, useState, useRef } from 'react' +import React, { + FunctionComponent, + useEffect, + useState, + useRef, + useCallback, +} from 'react' import type { MouseEvent } from 'react' import { Top } from '@nutui/icons-react' import classNames from 'classnames' import { BasicComponent, ComponentDefaults } from '@/utils/typings' -import requestAniFrame from '@/utils/raf' +import requestAniFrame, { cancelRaf } from '@/utils/raf' import { useRtl } from '@/packages/configprovider' -declare const window: any - export interface BackTopProps extends BasicComponent { target: string threshold: number @@ -46,33 +50,43 @@ export const BackTop: FunctionComponent< const [backTop, SetBackTop] = useState(false) const [scrollTop, SetScrollTop] = useState(0) let startTime = 0 - const scrollEl: any = useRef(null) - useEffect(() => { - init() - return () => removeEventListener() - }, []) + const scrollEl = useRef(null) + const cls = classNames( + classPrefix, + { + show: backTop, + }, + className + ) - const init = () => { + const scrollListener = useCallback(() => { + let top = null + if (scrollEl.current instanceof Window) { + top = scrollEl.current.scrollY + } else { + top = scrollEl.current?.scrollTop + } + SetScrollTop(top) + SetBackTop(top >= threshold) + }, [threshold]) + + const init = useCallback(() => { if (target && document.getElementById(target)) { - scrollEl.current = document.getElementById(target) as HTMLElement | Window + scrollEl.current = document.getElementById(target) } else { scrollEl.current = window } - addEventListener() - initCancelAniFrame() - } - const scrollListener = () => { - let top: any = null - if (scrollEl.current instanceof Window) { - top = scrollEl.current.pageYOffset - SetScrollTop(top) - } else { - top = scrollEl.current.scrollTop - SetScrollTop(top) + scrollEl.current?.addEventListener('scroll', scrollListener, false) + scrollEl.current?.addEventListener('resize', scrollListener, false) + }, [target, scrollListener]) + + useEffect(() => { + init() + return () => { + scrollEl.current?.removeEventListener('scroll', scrollListener, false) + scrollEl.current?.removeEventListener('resize', scrollListener, false) } - const showBtn = top >= threshold - SetBackTop(showBtn) - } + }, [init, scrollListener]) const scroll = (y = 0) => { if (scrollEl.current instanceof Window) { @@ -90,29 +104,14 @@ export const BackTop: FunctionComponent< scroll(y) cid = requestAniFrame(fn) if (t === duration || y === 0) { - window.cancelAnimationFrame(cid) + cancelRaf(cid) } }) } - const initCancelAniFrame = () => { - window.cancelAnimationFrame = window.webkitCancelAnimationFrame - } - - function addEventListener() { - scrollEl.current?.addEventListener('scroll', scrollListener, false) - scrollEl.current?.addEventListener('resize', scrollListener, false) - } - - function removeEventListener() { - scrollEl.current?.removeEventListener('scroll', scrollListener, false) - scrollEl.current?.removeEventListener('resize', scrollListener, false) - } - const goTop = (e: MouseEvent) => { onClick && onClick(e) - const otime = +new Date() - startTime = otime + startTime = +new Date() duration > 0 ? scrollAnimation() : scroll() } @@ -129,19 +128,7 @@ export const BackTop: FunctionComponent< } return ( -
{ - goTop(e) - }} - > +
goTop(e)}> {children || }
) diff --git a/src/packages/menu/menu.taro.tsx b/src/packages/menu/menu.taro.tsx index 5cb7a0ecd0..c6973c76ce 100644 --- a/src/packages/menu/menu.taro.tsx +++ b/src/packages/menu/menu.taro.tsx @@ -1,4 +1,10 @@ -import React, { FunctionComponent, useEffect, useRef, useState } from 'react' +import React, { + FunctionComponent, + useCallback, + useEffect, + useRef, + useState, +} from 'react' import classNames from 'classnames' import { ArrowDown, ArrowUp } from '@nutui/icons-react-taro' import { OptionItem, MenuItem } from '@/packages/menuitem/menuitem.taro' @@ -53,29 +59,30 @@ export const Menu: FunctionComponent> & { ...props, } const menuRef = useRef(null) + const [showMenuItem, setShowMenuItem] = useState([]) + const [menuItemTitle, setMenuItemTitle] = useState([]) const [isScrollFixed, setIsScrollFixed] = useState(false) + const cls = classNames(`nut-menu`, className, { + 'scroll-fixed': isScrollFixed, + }) const getScrollTop = (el: Element | Window) => { - return Math.max(0, 'scrollTop' in el ? el.scrollTop : el.pageYOffset) + return Math.max(0, 'scrollTop' in el ? el.scrollTop : el.scrollY) } - const onScroll = () => { - const { scrollFixed } = props - + const onScroll = useCallback(() => { const scrollTop = getScrollTop(window) const isFixed = scrollTop > (typeof scrollFixed === 'boolean' ? 30 : Number(scrollFixed)) setIsScrollFixed(isFixed) - } + }, [scrollFixed]) useEffect(() => { if (scrollFixed) { window.addEventListener('scroll', onScroll) } return () => window.removeEventListener('scroll', onScroll) - }, []) + }, [scrollFixed, onScroll]) - const [showMenuItem, setShowMenuItem] = useState([]) - const [menuItemTitle, setMenuItemTitle] = useState([]) const toggleMenuItem: MenuCallBackFunction = (index, from = 'NORMAL') => { showMenuItem[index] = !showMenuItem[index] if (showMenuItem[index]) { @@ -97,7 +104,6 @@ export const Menu: FunctionComponent> & { menuItemTitle[index] = text setMenuItemTitle([...menuItemTitle]) } - const cloneChildren = () => { return React.Children.map(children, (child, index) => { return React.cloneElement(child as any, { @@ -179,13 +185,7 @@ export const Menu: FunctionComponent> & { }) } return ( -
+
> & { ...props, } const menuRef = useRef(null) + const [showMenuItem, setShowMenuItem] = useState([]) + const [menuItemTitle, setMenuItemTitle] = useState([]) const [isScrollFixed, setIsScrollFixed] = useState(false) + const cls = classNames(`nut-menu`, className, { + 'scroll-fixed': isScrollFixed, + }) const getScrollTop = (el: Element | Window) => { - return Math.max(0, 'scrollTop' in el ? el.scrollTop : el.pageYOffset) + return Math.max(0, 'scrollTop' in el ? el.scrollTop : el.scrollY) } - const onScroll = () => { - const { scrollFixed } = props - + const onScroll = useCallback(() => { const scrollTop = getScrollTop(window) const isFixed = scrollTop > (typeof scrollFixed === 'boolean' ? 30 : Number(scrollFixed)) setIsScrollFixed(isFixed) - } + }, [scrollFixed]) useEffect(() => { if (scrollFixed) { window.addEventListener('scroll', onScroll) } return () => window.removeEventListener('scroll', onScroll) - }, []) + }, [scrollFixed, onScroll]) - const [showMenuItem, setShowMenuItem] = useState([]) - const [menuItemTitle, setMenuItemTitle] = useState([]) const toggleMenuItem: MenuCallBackFunction = (index, from = 'NORMAL') => { showMenuItem[index] = !showMenuItem[index] if (showMenuItem[index]) { @@ -180,13 +187,7 @@ export const Menu: FunctionComponent> & { }) } return ( -
+
Date: Thu, 10 Oct 2024 18:44:10 +0800 Subject: [PATCH 2/8] fix: add cancelanimation --- src/utils/raf.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/raf.ts b/src/utils/raf.ts index cab88a4277..0a11fcc46e 100644 --- a/src/utils/raf.ts +++ b/src/utils/raf.ts @@ -2,7 +2,7 @@ export const inBrowser = typeof window !== 'undefined' // 防频 function requestAniFrame() { - if (typeof window !== 'undefined') { + if (inBrowser) { const _window = window as any return ( _window.requestAnimationFrame || @@ -19,7 +19,8 @@ function requestAniFrame() { export function cancelRaf(id: number) { if (inBrowser) { - cancelAnimationFrame(id) + const _window = window as any + ;(_window.cancelAnimationFrame || _window.webkitCancelAnimationFrame)(id) } else { clearTimeout(id) } From 98fa2c7915c82bf03ab6fd672a9b950c1ebe8329 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 18:46:50 +0800 Subject: [PATCH 3/8] fix: format --- src/packages/backtop/backtop.taro.tsx | 8 +------- src/packages/backtop/backtop.tsx | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/packages/backtop/backtop.taro.tsx b/src/packages/backtop/backtop.taro.tsx index ceea9313c6..67783aa8fd 100644 --- a/src/packages/backtop/backtop.taro.tsx +++ b/src/packages/backtop/backtop.taro.tsx @@ -30,13 +30,7 @@ export const BackTop: FunctionComponent< } const classPrefix = 'nut-backtop' const [backTop, SetBackTop] = useState(false) - const cls = classNames( - classPrefix, - { - show: backTop, - }, - className - ) + const cls = classNames(classPrefix, { show: backTop }, className) // 监听用户滑动页面事件 usePageScroll((res) => { const { scrollTop } = res diff --git a/src/packages/backtop/backtop.tsx b/src/packages/backtop/backtop.tsx index dd5eab5466..1530a3ce39 100644 --- a/src/packages/backtop/backtop.tsx +++ b/src/packages/backtop/backtop.tsx @@ -51,13 +51,7 @@ export const BackTop: FunctionComponent< const [scrollTop, SetScrollTop] = useState(0) let startTime = 0 const scrollEl = useRef(null) - const cls = classNames( - classPrefix, - { - show: backTop, - }, - className - ) + const cls = classNames(classPrefix, { show: backTop }, className) const scrollListener = useCallback(() => { let top = null From e995cb61b023dd33190963a730ecef5611fbe431 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 19:13:08 +0800 Subject: [PATCH 4/8] fix: fixed by codecr --- src/packages/backtop/backtop.taro.tsx | 17 ++++++++++------- src/packages/menu/menu.taro.tsx | 5 ++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/packages/backtop/backtop.taro.tsx b/src/packages/backtop/backtop.taro.tsx index 67783aa8fd..975c812b04 100644 --- a/src/packages/backtop/backtop.taro.tsx +++ b/src/packages/backtop/backtop.taro.tsx @@ -1,4 +1,4 @@ -import React, { FunctionComponent, useState } from 'react' +import React, { FunctionComponent, useState, useCallback } from 'react' import type { MouseEvent } from 'react' import { usePageScroll, pageScrollTo } from '@tarojs/taro' import { Top } from '@nutui/icons-react-taro' @@ -29,14 +29,17 @@ export const BackTop: FunctionComponent< ...props, } const classPrefix = 'nut-backtop' - const [backTop, SetBackTop] = useState(false) + const [backTop, setBackTop] = useState(false) const cls = classNames(classPrefix, { show: backTop }, className) // 监听用户滑动页面事件 - usePageScroll((res) => { - const { scrollTop } = res - scrollTop >= threshold ? SetBackTop(true) : SetBackTop(false) - }) - // 返回顶部点击事件 + const handleScroll = useCallback( + (res: { scrollTop: number }) => { + const { scrollTop } = res + setBackTop(scrollTop >= threshold) + }, + [threshold] + ) + usePageScroll(handleScroll) const goTop = (e: MouseEvent) => { onClick && onClick(e) pageScrollTo({ diff --git a/src/packages/menu/menu.taro.tsx b/src/packages/menu/menu.taro.tsx index c6973c76ce..d2251d3c38 100644 --- a/src/packages/menu/menu.taro.tsx +++ b/src/packages/menu/menu.taro.tsx @@ -67,7 +67,10 @@ export const Menu: FunctionComponent> & { }) const getScrollTop = (el: Element | Window) => { - return Math.max(0, 'scrollTop' in el ? el.scrollTop : el.scrollY) + return Math.max( + 0, + el === window ? window.scrollY : (el as Element).scrollTop + ) } const onScroll = useCallback(() => { const scrollTop = getScrollTop(window) From 11b9288b442c51e4f80673a203195796618cfcfb Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 19:41:44 +0800 Subject: [PATCH 5/8] fix: test hit --- .../backtop/__test__/backtop.spec.tsx | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/packages/backtop/__test__/backtop.spec.tsx b/src/packages/backtop/__test__/backtop.spec.tsx index cd6d676352..0aec865738 100644 --- a/src/packages/backtop/__test__/backtop.spec.tsx +++ b/src/packages/backtop/__test__/backtop.spec.tsx @@ -8,21 +8,19 @@ import BackTop from '@/packages/backtop' test('backtop props test', () => { const handleClick = vi.fn() const { container } = render( - +
+ {new Array(24).fill(0).map((_, index) => { + return
我是测试数据{index}
+ })} + +
) - expect(container.querySelector('.nut-backtop')).toHaveAttribute( - 'style', - 'z-index: 900; right: 20px; bottom: 50px;' - ) - fireEvent.click(container) + const chooseTagEle = container.querySelectorAll('.backtop-button')[0] + fireEvent.click(chooseTagEle) expect(handleClick).toBeCalled }) From b497d1d020249794ad1f706dbb1333276d496444 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 20:01:27 +0800 Subject: [PATCH 6/8] fix: test codecr --- .../__test__/__snapshots__/menu.spec.tsx.snap | 109 ++++++++++++++++++ src/packages/menu/__test__/menu.spec.tsx | 24 +++- src/packages/menu/menu.tsx | 5 +- 3 files changed, 131 insertions(+), 7 deletions(-) diff --git a/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap b/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap index 1636a11ffc..cc86886c31 100644 --- a/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap +++ b/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap @@ -96,3 +96,112 @@ exports[`should match snapshot 1`] = `
`; + +exports[`should match snapshot of two columns in one line 1`] = ` + +
+
+
+
+ 全部商品 +
+ + + +
+
+
+ +
+
+
+`; + +exports[`should match snapshot of two columns in one line 2`] = ` + +
+
+
+ +`; diff --git a/src/packages/menu/__test__/menu.spec.tsx b/src/packages/menu/__test__/menu.spec.tsx index 8223c40ced..3fe2dc5986 100644 --- a/src/packages/menu/__test__/menu.spec.tsx +++ b/src/packages/menu/__test__/menu.spec.tsx @@ -3,7 +3,6 @@ import { act, fireEvent, render } from '@testing-library/react' import '@testing-library/jest-dom' import { Success } from '@nutui/icons-react' import Menu from '@/packages/menu' -import MenuItem from '@/packages/menuitem' function mockGetBoundingClientRect(rect: any): () => void { const spy = vi.spyOn(Element.prototype, 'getBoundingClientRect') @@ -29,7 +28,21 @@ test('should match snapshot', () => { ] const { asFragment } = render( - + + + ) + expect(asFragment()).toMatchSnapshot() +}) + +test('should match snapshot of two columns in one line', () => { + const options = [ + { text: '全部商品', value: 0 }, + { text: '新款商品', value: 1 }, + { text: '活动商品', value: 2 }, + ] + const { asFragment } = render( + + ) expect(asFragment()).toMatchSnapshot() @@ -52,26 +65,25 @@ test('test props', async () => { const { container, getByText } = render( - } activeTitleClass="activeTitleClass" inactiveTitleClass="inactiveTitleClass" onChange={testClick} /> + ) await act(() => { fireEvent.click(getByText('custom title')) - fireEvent.click(container.querySelectorAll('.nut-menu-container-item')[1]) - expect(testClick).toBeCalledWith({ text: '新款商品', value: 1 }) }) diff --git a/src/packages/menu/menu.tsx b/src/packages/menu/menu.tsx index b3eeeaeaea..5e0d8c1783 100644 --- a/src/packages/menu/menu.tsx +++ b/src/packages/menu/menu.tsx @@ -67,7 +67,10 @@ export const Menu: FunctionComponent> & { }) const getScrollTop = (el: Element | Window) => { - return Math.max(0, 'scrollTop' in el ? el.scrollTop : el.scrollY) + return Math.max( + 0, + el === window ? window.scrollY : (el as Element).scrollTop + ) } const onScroll = useCallback(() => { const scrollTop = getScrollTop(window) From bb1d254f1d7cb6fb0427cc37d95d49a34f655e6c Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 21:10:55 +0800 Subject: [PATCH 7/8] test: fix --- .../__test__/__snapshots__/menu.spec.tsx.snap | 12 --- src/packages/menu/__test__/menu.spec.tsx | 73 ++++++++++++------- src/packages/menuitem/menuitem.tsx | 32 ++++---- 3 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap b/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap index cc86886c31..d2d231afa6 100644 --- a/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap +++ b/src/packages/menu/__test__/__snapshots__/menu.spec.tsx.snap @@ -193,15 +193,3 @@ exports[`should match snapshot of two columns in one line 1`] = `
`; - -exports[`should match snapshot of two columns in one line 2`] = ` - -
-
-
- -`; diff --git a/src/packages/menu/__test__/menu.spec.tsx b/src/packages/menu/__test__/menu.spec.tsx index 3fe2dc5986..f436a229ae 100644 --- a/src/packages/menu/__test__/menu.spec.tsx +++ b/src/packages/menu/__test__/menu.spec.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import React, { useRef } from 'react' import { act, fireEvent, render } from '@testing-library/react' import '@testing-library/jest-dom' import { Success } from '@nutui/icons-react' @@ -27,7 +27,7 @@ test('should match snapshot', () => { { text: '活动商品', value: 2 }, ] const { asFragment } = render( - + ) @@ -49,6 +49,42 @@ test('should match snapshot of two columns in one line', () => { }) test('test props', async () => { + const App = () => { + const options = [ + { text: '全部商品', value: 0 }, + { text: '新款商品', value: 1 }, + { text: '活动商品', value: 2 }, + ] + + const itemRef = useRef(null) + return ( + + } + activeTitleClass="activeTitleClass" + inactiveTitleClass="inactiveTitleClass" + onChange={testClick} + /> + + +
{ + ;(itemRef.current as any)?.toggle(false) + }} + > + 确认 +
+
+
+ ) + } mockGetBoundingClientRect({ width: 300, height: 100, @@ -56,30 +92,8 @@ test('test props', async () => { top: 0, right: 300, }) - const options = [ - { text: '全部商品', value: 0 }, - { text: '新款商品', value: 1 }, - { text: '活动商品', value: 2 }, - ] const testClick = vi.fn((val) => undefined) - - const { container, getByText } = render( - - } - activeTitleClass="activeTitleClass" - inactiveTitleClass="inactiveTitleClass" - onChange={testClick} - /> - - - ) + const { container, getByText } = render() await act(() => { fireEvent.click(getByText('custom title')) @@ -87,6 +101,15 @@ test('test props', async () => { expect(testClick).toBeCalledWith({ text: '新款商品', value: 1 }) }) + const overlayContainer = container.querySelectorAll( + '.nut-menu-container-overlay' + )[0] + + fireEvent.click(overlayContainer) + + const menuitem = container.querySelectorAll('.test-menu-item')[0] + fireEvent.click(menuitem) + expect(container.querySelector('.custom-className')).toHaveClass( 'custom-className' ) diff --git a/src/packages/menuitem/menuitem.tsx b/src/packages/menuitem/menuitem.tsx index 203ac684a2..6f81dd1415 100644 --- a/src/packages/menuitem/menuitem.tsx +++ b/src/packages/menuitem/menuitem.tsx @@ -1,6 +1,7 @@ import React, { CSSProperties, forwardRef, + useCallback, useEffect, useImperativeHandle, useMemo, @@ -87,9 +88,23 @@ export const MenuItem = forwardRef((props: Partial, ref) => { useEffect(() => { setShowPopup(show) }, [show]) + + const getParentOffset = useCallback(() => { + setTimeout(() => { + const p = parent.menuRef.current + if (p) { + const rect = p.getBoundingClientRect() + setPosition({ + height: rect.height, + top: rect.top, + }) + } + }) + }, [parent.menuRef]) + useEffect(() => { getParentOffset() - }, [showPopup]) + }, [showPopup, getParentOffset]) useImperativeHandle(ref, () => ({ toggle: (s: boolean) => { @@ -128,19 +143,6 @@ export const MenuItem = forwardRef((props: Partial, ref) => { return getScrollParent(parent.menuRef, window) }, [parent.menuRef]) - const getParentOffset = () => { - setTimeout(() => { - const p = parent.menuRef.current - if (p) { - const rect = p.getBoundingClientRect() - setPosition({ - height: rect.height, - top: rect.top, - }) - } - }) - } - useEffect(() => { if (!parent.lockScroll) { scrollParent?.addEventListener('scroll', getParentOffset, false) @@ -148,7 +150,7 @@ export const MenuItem = forwardRef((props: Partial, ref) => { scrollParent?.removeEventListener('scroll', getParentOffset, false) } } - }, []) + }, [parent.lockScroll, scrollParent, getParentOffset]) const getPosition = (): CSSProperties => { return direction === 'down' From 693adb6005dd33ff9e065ca55027135bb66b1bb2 Mon Sep 17 00:00:00 2001 From: hanyuxinting Date: Thu, 10 Oct 2024 21:14:12 +0800 Subject: [PATCH 8/8] fix: lint of menuitem --- src/packages/menuitem/menuitem.taro.tsx | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/packages/menuitem/menuitem.taro.tsx b/src/packages/menuitem/menuitem.taro.tsx index 041db8c4a2..f8ce05ce54 100644 --- a/src/packages/menuitem/menuitem.taro.tsx +++ b/src/packages/menuitem/menuitem.taro.tsx @@ -90,9 +90,21 @@ export const MenuItem = forwardRef((props: Partial, ref) => { useEffect(() => { setShowPopup(show) }, [show]) + + const getParentOffset = useCallback(() => { + setTimeout(async () => { + const p = parent.menuRef.current + const rect = await getRectByTaro(p) + setPosition({ + height: rect.height, + top: rect.top, + }) + }, 100) + }, [parent.menuRef]) + useEffect(() => { getParentOffset() - }, [showPopup]) + }, [showPopup, getParentOffset]) const windowHeight = useMemo(() => getSystemInfoSync().windowHeight, []) const updateItemOffset = useCallback(() => { @@ -106,7 +118,8 @@ export const MenuItem = forwardRef((props: Partial, ref) => { }) } }) - }, [direction, windowHeight]) + }, [direction, windowHeight, parent.lockScroll, parent.menuRef]) + usePageScroll(updateItemOffset) useImperativeHandle(ref, () => ({ @@ -136,16 +149,7 @@ export const MenuItem = forwardRef((props: Partial, ref) => { top: 0, height: 0, }) - const getParentOffset = () => { - setTimeout(async () => { - const p = parent.menuRef.current - const rect = await getRectByTaro(p) - setPosition({ - height: rect.height, - top: rect.top, - }) - }, 100) - } + const isShow = () => { if (showPopup) return {} return { display: 'none' }