-
Notifications
You must be signed in to change notification settings - Fork 2.5k
fix: error 6945, antd-mobile slide calculation error #6946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -116,7 +116,16 @@ export const MultiImageViewer = forwardRef< | |||||||||||||||||||||||||||||||||||||||||||||
| slidesRef.current?.swipeTo(index, immediate) | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| const viewportWidth = (function () { | ||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||
| const host = props.getContainer && props.getContainer(); | ||||||||||||||||||||||||||||||||||||||||||||||
| if (host && host.getBoundingClientRect) { | ||||||||||||||||||||||||||||||||||||||||||||||
| const w = host.getBoundingClientRect().width; | ||||||||||||||||||||||||||||||||||||||||||||||
| if (w && w > 0) return w; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) {} | ||||||||||||||||||||||||||||||||||||||||||||||
| return typeof window !== 'undefined' ? window.innerWidth : 375; | ||||||||||||||||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+119
to
+128
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 修复:GetContainer 形态未全覆盖,HTMLElement 会被误当函数调用,导致宽度始终退回 window 当前写法在 可在原位置直接替换为: - const viewportWidth = (function () {
- try {
- const host = props.getContainer && props.getContainer();
- if (host && host.getBoundingClientRect) {
- const w = host.getBoundingClientRect().width;
- if (w && w > 0) return w;
- }
- } catch (e) {}
- return typeof window !== 'undefined' ? window.innerWidth : 375;
- })();
+ const viewportWidth = (function () {
+ try {
+ const container = props.getContainer;
+ const host = typeof container === 'function' ? container() : container;
+ const w =
+ host && typeof (host as any).getBoundingClientRect === 'function'
+ ? (host as any).getBoundingClientRect().width
+ : 0;
+ if (w > 0) return w;
+ } catch {}
+ return typeof window !== 'undefined' ? window.innerWidth : 375;
+ })();可选增强(推荐后续跟进):当容器尺寸或方向变化时动态重算宽度,避免横竖屏切换后滑动距离与指示器错位。 附示例(需在文件顶部引入 - const viewportWidth = (function () { /* 立即求值 */ })();
+ const [viewportWidth, setViewportWidth] = useState(375);
+ const measure = useCallback(() => {
+ try {
+ const container = props.getContainer;
+ const host = typeof container === 'function' ? container() : container;
+ const w =
+ host && typeof (host as any).getBoundingClientRect === 'function'
+ ? (host as any).getBoundingClientRect().width
+ : 0;
+ return w > 0 ? w : (typeof window !== 'undefined' ? window.innerWidth : 375);
+ } catch { return typeof window !== 'undefined' ? window.innerWidth : 375; }
+ }, [props.getContainer]);
+ useLayoutEffect(() => {
+ const update = () => setViewportWidth(measure());
+ update();
+ if (typeof window !== 'undefined') {
+ window.addEventListener('resize', update);
+ let ro: ResizeObserver | null = null;
+ const container = props.getContainer;
+ const host = typeof container === 'function' ? container() : container;
+ if (host && 'ResizeObserver' in window) {
+ ro = new ResizeObserver(update); ro.observe(host as Element);
+ }
+ return () => { window.removeEventListener('resize', update); ro?.disconnect(); };
+ }
+ }, [measure, props.getContainer]);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| const onSlideChange = useCallback( | ||||||||||||||||||||||||||||||||||||||||||||||
| (newIndex: number) => { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (newIndex === index) return | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -150,6 +159,7 @@ export const MultiImageViewer = forwardRef< | |||||||||||||||||||||||||||||||||||||||||||||
| onTap={props.onClose} | ||||||||||||||||||||||||||||||||||||||||||||||
| maxZoom={props.maxZoom} | ||||||||||||||||||||||||||||||||||||||||||||||
| imageRender={props.imageRender} | ||||||||||||||||||||||||||||||||||||||||||||||
| viewportWidth={viewportWidth} | ||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,13 +23,17 @@ export type SlidesType = { | |
| image: string, | ||
| { ref, index }: { ref: RefObject<HTMLImageElement>; index: number } | ||
| ) => ReactNode | ||
| viewportWidth: number | ||
| } | ||
|
Comment on lines
+26
to
27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain类型一致性:maxZoom 在父组件可为 'auto',此处仅为 number
可选其一: - maxZoom: number
+ maxZoom: number | 'auto'或在父组件传参前将 🏁 Script executed: #!/bin/bash
# 查找 ImageViewerProps 定义及其 maxZoom 类型
rg -nP --type=ts "interface\s+ImageViewerProps" -nC3
# 查找 MultiImageViewerProps 定义及其继承关系
rg -nP --type=ts "interface\s+MultiImageViewerProps" -nC3
# 查找 SlidesType 定义,确认 maxZoom 类型
rg -nP --type=ts "type\s+SlidesType" -nC3Length of output: 1268 🏁 Script executed: #!/bin/bash
# 查找 slides.tsx 文件路径
fd slides.tsx -t f
# 打印 SlidesType 定义及周围上下文
rg -n 'type SlidesType' -C5 src
# 查找 ImageViewerProps 定义及 maxZoom 类型
rg -n 'interface ImageViewerProps' -C5 src
# 查找 MultiImageViewerProps 定义及继承关系
rg -n 'interface MultiImageViewerProps' -C5 srcLength of output: 774 🏁 Script executed: #!/bin/bash
# 列出 image-viewer 组件目录下所有文件
fd -t f src/components/image-viewer
# 搜索 MultiImageViewer 组件定义
rg -nP 'export (function|const) MultiImageViewer' -C5 src
# 搜索 MultiImageViewerProps 定义或引用
rg -nP 'MultiImageViewerProps' -C5 src
# 搜索 ImageViewerProps 定义或引用
rg -nP 'ImageViewerProps' -C5 srcLength of output: 12252 同步 SlidesType.maxZoom 与父组件 Prop 类型 maxZoom 在 ImageViewerProps/MultiImageViewerProps 中可为 number | 'auto',但 SlidesType 定义为 number,若传入
🤖 Prompt for AI Agents |
||
| export type SlidesRef = { | ||
| swipeTo: (index: number, immediate?: boolean) => void | ||
| } | ||
|
|
||
| export const Slides = forwardRef<SlidesRef, SlidesType>((props, ref) => { | ||
| const slideWidth = window.innerWidth + convertPx(16) | ||
| const baseWidth = props.viewportWidth | ||
|
|
||
| const slideWidth = baseWidth + convertPx(16) | ||
|
|
||
| const [{ x }, api] = useSpring(() => ({ | ||
| x: props.defaultIndex * slideWidth, | ||
| config: { tension: 250, clamp: true }, | ||
|
|
@@ -51,6 +55,7 @@ export const Slides = forwardRef<SlidesRef, SlidesType>((props, ref) => { | |
| })) | ||
|
|
||
| const dragLockRef = useRef(false) | ||
|
|
||
| const bind = useDrag( | ||
| state => { | ||
| if (dragLockRef.current) return | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic for determining
viewportWidthhas a bug and can be improved for robustness.props.getContainer && props.getContainer()is incorrect. ThegetContainerprop can be anHTMLElementobject. In that case,props.getContainer()will throw aTypeError. This error is silently caught, causing the logic to incorrectly fall back to usingwindow.innerWidth, which defeats the purpose of this change.catch (e) {}block swallows all errors, which can make debugging very difficult. It's better practice to at least log errors during development.w && w > 0is redundant.w > 0is sufficient, as0is falsy.I've provided a suggestion that fixes the bug while keeping the structure of your code.