I'm building a blog site with MDX & NextJS. I'm defining a custom image component that will make use of the Next <Image>
component. The issue I'm having is relatively small, but I've been struggling to find an answer to it.
The basic question is: If I have a variable of string | undefined
, is there any way in React to only pass that variable to an optional prop if it's defined? I'm pretty new to React, so this might be something super basic.
My reasoning for needing this is that the custom MDX image component should take ImgHTMLAttributes<HTMLImageElement>
as props. All of these props are defined as someType | undefined
, which makes sense since HTML attributes are optional.
My issue comes in passing these props down to Next image. How do I pass the optional src
, alt
, width
, and height
props when they are defined in the original image but not when they aren't?
The specific error I'm getting is Type 'string | undefined' is not assignable to type 'string | StaticImport'
, which makes perfect sense.
I tried something like this:
const src = props.src != undefined ? props.src : "";
const alt = props.alt != undefined ? props.alt : "";
const width = props.width != undefined ? props.width : "";
const height = props.height != undefined ? props.height : "";
which was ugly, and also didn't really solve my problem. I don't want to be passing width when its undefined for example.
For the properties you need to supply defaults for instead of undefined
, you use nullish coalescing, like this:
export function ImageWrapper(props: ImageWrapperProps) {
return <Image
{...props}
src={props.src ?? ValidDefaultSrc}
alt={props.alt ?? ValidDefaultAlt}
/>;
}
The order is important there, first you spread out all of the properties from props
, then override src
and alt
with versions with defaults. Those are the only two required properties in the props for the Next Image
component.
Note that I haven't just used ""
as the defaults. The src
and alt
props are required on Image
for a reason. I don't use Next.js, but it seems unlikely that src=""
(in particular) is a valid value, and alt=""
may be valid, but it's not accessible to users of screen readers and such. But I suspect you just used those in the question as placeholders.