最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - NextJs Link component wrapping Image causes errors when mapping over array unless used in top level page component

programmeradmin5浏览0评论

I am trying to utilise NextJs's <Link /> tag to wrap a NextJs <Image /> in my application, to map over an array of data. If I place a <Link /> in a top level page ponent everything plays nicely and renders correctly. However if I try to abstract this out into a sub ponent and then embed the sub ponent in the page ponent I receive errors telling me Error: Multiple children were passed to <Link> with hrefof/test but only one child is supported unless I remove all line breaks in the source code.

For example this works

// pages/index.js
import Link from 'next/link';
import Image from 'next/image';

export default function Home({links}) {
    return (
        <>
            <div id="container">
                <main>
                    {links.map(link => {
                        return <Link key={link.link} href={link.link}>
                            <a><Image src={link.imageUrl} width={400} height={400}/></a>
                        </Link>;
                    })
                    }
                </main>
            </div>

        </>
    );
}

export async function getStaticProps() {
    const response = await fetch('http://localhost:3000/api/links');
    const links = await response.json();
    return {
        props: {
            links
        },
    }
}

This also works

// pages/index.js
import Links from '../ponents/Links';

export default function Home({links}) {
    return (
        <>
            <div id="container">
                <main>
                     <Links links={links}/>
                </main>
            </div>

        </>
    );
}

export async function getStaticProps() {
    const response = await fetch('http://localhost:3000/api/links');
    const links = await response.json();
    return {
        props: {
            links
        },
    }
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';

export default function Links({links}) {
    return links.map(link => {
            return <Link key={link.link} href={link.link}><a><Image src={link.imageUrl} width={400} height={400}/></a></Link>;
        },
    );
}

However this fails

// pages/index.js
import Links from '../ponents/Links';

export default function Home({links}) {
    return (
        <>
            <div id="container">
                <main>
                     <Links links={links}/>
                </main>
            </div>

        </>
    );
}

export async function getStaticProps() {
    const response = await fetch('http://localhost:3000/api/links');
    const links = await response.json();
    return {
        props: {
            links
        },
    }
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';

export default function Links({links}) {
    return links.map(link => {
            return <Link key={link.link} href={link.link}>
                <a>
                    <Image src={link.imageUrl} width={400} height={400}/>
                </a>
            </Link>;
        },
    );
}

Any help appreciated!

I am trying to utilise NextJs's <Link /> tag to wrap a NextJs <Image /> in my application, to map over an array of data. If I place a <Link /> in a top level page ponent everything plays nicely and renders correctly. However if I try to abstract this out into a sub ponent and then embed the sub ponent in the page ponent I receive errors telling me Error: Multiple children were passed to <Link> with hrefof/test but only one child is supported https://nextjs/docs/messages/link-multiple-children unless I remove all line breaks in the source code.

For example this works

// pages/index.js
import Link from 'next/link';
import Image from 'next/image';

export default function Home({links}) {
    return (
        <>
            <div id="container">
                <main>
                    {links.map(link => {
                        return <Link key={link.link} href={link.link}>
                            <a><Image src={link.imageUrl} width={400} height={400}/></a>
                        </Link>;
                    })
                    }
                </main>
            </div>

        </>
    );
}

export async function getStaticProps() {
    const response = await fetch('http://localhost:3000/api/links');
    const links = await response.json();
    return {
        props: {
            links
        },
    }
}

This also works

// pages/index.js
import Links from '../ponents/Links';

export default function Home({links}) {
    return (
        <>
            <div id="container">
                <main>
                     <Links links={links}/>
                </main>
            </div>

        </>
    );
}

export async function getStaticProps() {
    const response = await fetch('http://localhost:3000/api/links');
    const links = await response.json();
    return {
        props: {
            links
        },
    }
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';

export default function Links({links}) {
    return links.map(link => {
            return <Link key={link.link} href={link.link}><a><Image src={link.imageUrl} width={400} height={400}/></a></Link>;
        },
    );
}

However this fails

// pages/index.js
import Links from '../ponents/Links';

export default function Home({links}) {
    return (
        <>
            <div id="container">
                <main>
                     <Links links={links}/>
                </main>
            </div>

        </>
    );
}

export async function getStaticProps() {
    const response = await fetch('http://localhost:3000/api/links');
    const links = await response.json();
    return {
        props: {
            links
        },
    }
}
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';

export default function Links({links}) {
    return links.map(link => {
            return <Link key={link.link} href={link.link}>
                <a>
                    <Image src={link.imageUrl} width={400} height={400}/>
                </a>
            </Link>;
        },
    );
}

Any help appreciated!

Share Improve this question asked Feb 21, 2022 at 23:33 bryansmullenbryansmullen 651 gold badge2 silver badges5 bronze badges 1
  • You can't have any extra spaces inside the <Link> tag. See Next.js: Error: React.Children.only expected to receive a single React element child. – juliomalves Commented Apr 27, 2022 at 22:24
Add a ment  | 

2 Answers 2

Reset to default 3

I'm using nextjs with tailwindcss.
When wrapping Image with <></>, my mouse didn't change to a little hand when hovering the element and clicking it does nothing.
And when wrapping with <a></a>, the image doesn't line up with other elements even using flex justify-center items-center on Link(at least in my case).

So this is my solution:

const iconSize=20;
<Link href="/">
      <div className="hover:cursor-pointer flex justify-center items-center">
            <Image
              src="/your_image.png"
              alt="clickable image"
              width={iconSize}
              height={iconSize}
            />
      </div>
</Link>

my nextjs version:

Next.js v12.2.3

try the code bellow

const CustomLink = React.forwardRef(({ href, children, ...rest }, ref) => (
  <a href={href} ref={ref} {...rest}>
    {children}
  </a>
));
// ponents/Links.js
import Image from 'next/image';
import Link from 'next/link';

export default function Links({links}) {
   return links.map(link => {
            return <Link key={link.link} passHref href={link.link}>
                <Image src={link.imageUrl} width={400} height={400}/>
            </Link>;
       },
   );
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论