我有一个组件,看起来像这样:
import React, { FC, ImgHTMLAttributes, useEffect, useRef, useState } from "react";
import NextImage from "next/image";
import checkInViewIntersectionObserver from "@/utils/isInViewPortIntersectionObserver";
import PlaceIcon from "./PlaceIcon";
export interface NcImageProps extends ImgHTMLAttributes<HTMLImageElement> {
containerClassName?: string;
}
const NcImage: FC<NcImageProps> = ({
containerClassName = "",
alt = "nc-imgs",
src = "",
className = "object-cover w-full h-full",
...args
}) => {
const isMounted = useRef(false);
const _containerRef = useRef(null);
const [__src, set__src] = useState("");
const [imageLoaded, setImageLoaded] = useState(false);
useEffect(() => {
let _imageEl: HTMLImageElement | null = null;
isMounted.current = true;
const _imageOnViewPort = () => {
if (!src) {
_handleImageLoaded();
return true;
}
_imageEl = new Image();
if (_imageEl) {
_imageEl.src = src;
_imageEl.addEventListener("load", _handleImageLoaded);
}
return true;
};
const _handleImageLoaded = () => {
if (!isMounted.current) return;
setImageLoaded(true);
set__src(src);
};
const _checkInViewPort = () => {
if (!_containerRef.current) return;
checkInViewIntersectionObserver({
target: _containerRef.current,
options: {
root: null,
rootMargin: "0%",
threshold: 0,
},
freezeOnceVisible: true,
callback: _imageOnViewPort,
});
};
const _initActions = async () => {
_checkInViewPort();
};
_initActions();
return () => {
isMounted.current = false;
};
}, [src]);
const renderLoadingPlaceholder = () => {
return (
<div
className={`${className} flex items-center justify-center bg-neutral-200 dark:bg-neutral-6000 text-neutral-100 dark:text-neutral-500`}
>
<div className="h-2/4 max-w-[50%]">
<PlaceIcon />
</div>
</div>
);
};
return (
<div className={`nc-NcImage ${containerClassName}`} data-nc-id="NcImage" ref={_containerRef}>
{__src && imageLoaded ? (
<NextImage src={__src} className={className} alt={alt} {...args} />
) : (
renderLoadingPlaceholder()
)}
</div>
);
};
export default NcImage;
它最初使用<img ...
而不是NextImage
,一切正常。我想把它改为Next.js的Image
组件。当我这样做时,我得到了以下错误:
Type '{ crossOrigin?: "" | "anonymous" | "use-credentials" | undefined; decoding?: "async" | "auto" | "sync" | undefined; height?: string | number | undefined; loading?: "eager" | "lazy" | undefined; ... 263 more ...; alt: string; }' is not assignable to type '{ src: string | StaticImport; alt: string; width?: SafeNumber | undefined; height?: SafeNumber | undefined; fill?: boolean | undefined; loader?: ImageLoader | undefined; ... 11 more ...; lazyRoot?: string | undefined; }'.
Types of property 'width' are incompatible.
Type 'string | number | undefined' is not assignable to type 'SafeNumber | undefined'.
Type 'string' is not assignable to type 'SafeNumber | undefined'.ts(2322)
我不完全知道如何修复它,因为我没有使用width
的任何地方。
我想到的只是从NcImage
的输入中获取它,然后更改它的类型:
const newWidth = typeof width === 'number' ? SafeNumber(width) : width;
但是我不确定SafeNumber是什么或者从哪里导入它。解决这个问题的正确方法是什么?
1条答案
按热度按时间2fjabf4q1#
由于您正在呈现Next.js
Image
标记,因此请使用相应的props类型ImageProps
,如下所示:有了这个,你的错误就消失了。