I’m trying to create a react component (NextJS), which is a hexagon with an image inside it. The component should render the image that was sent as a prop. However, when I try to use multiple components with different images in the HeagonWall, all hexagons render the image of the first instance of that component instead of rendering both images accordingly. How can I solve this issue?
//hexagon-tile.tsx
interface HexagonTileProp {
imageLink: string,
imageId: string
}
export default function HexagonTile({ imageLink, imageId }: HexagonTileProp) {
return (
<div>
<svg height='387' viewBox='0 0 595 687' fill='none' xmlns='http://www.w3.org/2000/svg' xmlnsXlink='http://www.w3.org/1999/xlink'>
<path d='M297.5 0L594.98 171.75V515.25L297.5 687L0.0202637 515.25V171.75L297.5 0Z' fill='url(#pattern0)' />
<defs>
<pattern id='pattern0' patternContentUnits='objectBoundingBox' width='1' height='1'>
<use xlinkHref={`#${imageId}`} transform='translate(-0.3) scale(0.000625)' />
</pattern>
<image id={imageId} width='2560' height='1600' xlinkHref={imageLink} />
</defs>
</svg>
</div>
);
}
//hexagon-wall.tsx
export default function HexagonWall() {
return (
<div>
<HexagonTile imageLink='https://cdn.test.com/testimg/testimg-1.jpg' imageId={crypto.randomUUID()} />
<HexagonTile imageLink='https://cdn.test.com/testimg/testimg-2.jpg' imageId={crypto.randomUUID()} />
</div>
);
}
The expected outcome should have different images inside two hexagons. But this is the actual outcome:
2
Answers
You should either be auto generating the image and pattern ids, or passing id in as a prop. You have hardcoded them for every image / pattern, so every svg will just take the first image / pattern with that id in the DOM.
You can use
crypto.randomUUID()
to generate a unique id.Note support for this function: https://caniuse.com/mdn-api_crypto_randomuuid
Note
xlink:href
is deprecated you can just usehref
.Stackblitz: https://stackblitz.com/edit/stackblitz-starters-vq1t45?file=src%2FApp.tsx
You’re defining a duplicate pattern id.
Fix it by using your
id
props :