nextjs: Multiple children were passed to <Link> with `href` of 'x' but only one child is supported - next.js

I'm not passing multiple children to the Link, why am I getting this error? The error is:
"Multiple children were passed to with href of /post/61703ea640ff7eef1e1e7e75 but only one child is supported"
return (
<>
{head()}
<div className="container-fluid"
style={{
backgroundImage: "url( "+ "/images/default.jpg"+ ")",
backgroundAttachment: "fixed",
padding: "100px 0px 75px 0px",
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
backgroundPosition: 'center center',
display: 'block'
}}>
<h1 className="display-1 font-weight-bold text-center py-5">MERNCAMP</h1>
</div>
<div className="container">
<div className="row pt-5">
{posts.map((post) => (
<div key={post._id} className="col-md-4">
<Link href={`/post/view/${post._id}`}>
<a>
<PostPublic key={post._id} post={post} />
</a>
</Link>
</div>
))}
</div>
</div>
</>
)

Wrap the entire link with one div
<Link key={post._id} href={`/post/${post.slug.current}`}>
<div>
<div>
<img src={urlFor(post.mainImage).url()} alt=''></img>
</div>
<div>
<p>{post.title}</p>
<p>
{post.description} by {post.author.n`enter code here`ame}
</p>
</div>
<img src={urlFor(post.author.image).url()!} alt=''></img>
</div>
</Link>

I don't see anything wrong with your code.
Are you sure that's how it's written in your source file? This error usually happens if you have a space in between the <Link> and the <a> tags.
Example:
...
{posts.map((post) => (
<div key={post._id} className="col-md-4">
<Link href={`/post/view/${post._id}`}> <a>
<PostPublic key={post._id} post={post} />
</a></Link>
</div>
))}
You see the space in between the tags in <Link href={`/post/view/${post._id}`}> <a>

If it helps any one i was getting same error in following e.g code
<ul>
<li>
<Link href="/something">Link to some page</Link>
</li>
</ul>
I fixed it by enclosing the text inside a p tag, seems like every block of text/word is considered as new unique "children"
<ul>
<li>
<Link href="/something">
<p>Link to some page</p>
</Link>
</li>
</ul>

I know that is too late but just in case...
I got the same error and I solved by just restarting the development server, I know that is so silly but worked for me.
Also, be sure that your component <PostPublic /> doesn't have Link inside, my theory is probably is nesting links to your main Link child that is been mapped. Hope can help that to anyone.

Related

Does anyone Know how I could fix this, it keeps giving me this error "Cannot find name 'Navbar'." I'v tried changing the files from ".ts" to ".tsx"

here it the code that I'm busy with
Any help would be appreciated.
I know this isn't such a complicated issue but
I just Don't know how to fix this
If someone could at least just tell me where to fix it
Or just tell me what the actual problem is.
import Image from 'next/image'
import { Inter } from '#next/font/google'
import 'bulma/css/bulma.css'
import styles from './page.module.css'
import { Head } from 'next/document'
const inter = Inter({ subsets: ['latin'] })
export default function VendingMachine() {
return (
<><div>
<Head>
<title>VendingMachine App</title>
<meta name="description" content="A blockchain vending app" />
</Head>
<Navbar className="navbar">
<div className='container'>
<div className="navbar-brand">
<h1>Vending Machine</h1>
</div>
</div>
</Navbar>
</div>
<main className={styles.main}>
<div className={styles.description}>
<p>
Get started by editing
<code className={styles.code}>src/app/page.tsx</code>
</p>
<div>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{' '}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className={styles.vercelLogo}
width={100}
height={24}
priority />
</a>
</div>
</div>
<div className={styles.center}>
<Image
className={styles.logo}
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority />
<div className={styles.thirteen}>
<Image src="/thirteen.svg" alt="13" width={40} height={31} priority />
</div>
</div>
<div className={styles.grid}>
I've tried multiple things

How to use state as "active" indicator in React JS

I have a state that shows which menu tab is currently active
const [activeTab, setActiveTab] = useState("home");
I use the state as class on my mark up
<div className={`${activeTab}`}>
<img src={Assets.Home} alt="Home" />
<p>Home</p>
</div>
<div className={`${activeTab}`}>
<img src={Assets.Wallet} alt="Wallet" />
<p>Wallet</p>
</div>
But that doesn't work since when the state changes it changes the class names of both divs. Now I want a way to use state as active indicator . I tried attaching an extra class for each div like this
<div className={`home ${activeTab}`}>
<img src={Assets.Home} alt="Home" />
<p>Home</p>
</div>
<div className={`wallet ${activeTab}`>
<img src={Assets.Wallet} alt="Wallet" />
<p>Wallet</p>
</div>
So that I can target in CSS. Like this
.home.home{
//some code
}
Whilst the above approach works it is messy. I would ideally like to just use the state as the class name without any extra addition. How can I do that?
Use conditional rendering to check if the specific class is active and assign it a single class active in that case:
const [activeTab, setActiveTab] = useState("home");
<div className={`${activeTab === 'home' ? 'active' : ''}`}>
<img src={Assets.Home} alt="Home" />
<p>Home</p>
</div>
<div className={`${activeTab === 'wallet' ? 'active' : ''}`}>
<img src={Assets.Wallet} alt="Wallet" />
<p>Wallet</p>
</div>
You can then target the active class in CSS by defining:
.active {
...
}
add the onClick handler at the tag to handle the activeTab state like <div onClick={() => setActiveTab("home")} className={${activeTab}}>{...}</div>
For your case you only need to do this:
<div onClick={() => setActiveTab("home")} className={`home ${activeTab}`}>
<img src={Assets.Home} alt="Home" />
<p>Home</p>
</div>
<div onClick={() => setActiveTab("wallet")} className={`wallet ${activeTab}`}>
<img src={Assets.Wallet} alt="Wallet" />
<p>Wallet</p>
</div>

Center image in bootstrap navbar with uneven ends

I would like to center the brand logo in my page and it is currently to the side:
Here is my code:
export default function NavBar() {
return (
<Navbar bg='light' fixed='top' className='navbar py-1 '>
<Container>
<HiOutlineMenuAlt4 />
<Navbar.Brand className="justify-content-center">
<img src={publicgoodslogo} width="120" height="65" ></img>
</Navbar.Brand>
<Navbar.Collapse className="justify-content-end">
<Nav>
<Nav.Link><GoSearch /></Nav.Link>
</Nav>
<Navbar.Text>
Cart:
</Navbar.Text>
</Navbar.Collapse>
<Nav>
0
</Nav>
</Container>
</Navbar>
)
According to the docs I should just be able to use justify-content-center but that doesn't work. Is it because I need to wrap the menu icon in something?

How would go about to display items on same line in react?

I am new to using react and i have started to write a program but i have hit a wall and don't know how to overcome it.
I am trying to display movie poster with their name and release date on the side of the poster. If you see the screenshot you can see thats not the case right now, the text is being placed below the poster.
How would i go about to make the poster and text side by side?
this is my render code if the problem is within there:
return (
<div className="App">
<h1>Movie logger app</h1>
<input value={word} onChange={handleChange} />
<button onClick={getMovieName}>Find Movie</button>
{data.map((item) => {
return <div key={item.id}>
<img src={item.poster} alt=""/> <h2>{item.title}</h2> <h4>{item.date}</h4>
</div>;
})}
</div>
);
This is more of a CSS question than a React question. You can try a flexbox layout, like so:
{data.map((item) => (
<div key={item.id} style={{ display: "flex" }}>
<img src={item.poster} alt="" />
<div style={{ marginLeft: 20, display: "flex", flexDirection: "column" }}>
<h2>{item.title}</h2>
<h4>{item.date}</h4>
</div>
</div>
))}
You could use bootstrap grid system to give each element the half of the screen.
https://getbootstrap.com/docs/4.0/layout/grid/
{data.map((item) => {
<div class="container">
<div class="row">
<div class="col-6">
<img src={item.poster} alt=""/>
</div>
<div class="col-6">
<h2>{item.title}</h2> <h4>{item.date}</h4>
</div>
</div>
</div>
})}
Another option could be to position your elements in a table that cover all the screen (not recommended )

Creating a web page with bootstrap with content centred

All my pages use the entire width.
I would like the pages to conform to a page with the content having large margins automatically and I cant seem to do it.
I am using react and bootstrap.
I have tried using the following but it still uses 100% of the width...
<div class="container">
<div class="row">
<h1>Scheduler goes here!</h1>
</div>
</div>
I also tried adding this wrapper div
<div class="col-sm-12">
EDIT:
This is not working for me at the moment. I tried to add the container as per the answer below however my navbar is appearing correctly but the page is sitting right on the left margin of the screen.
I am using react-bootstrap.
my menu, which is displaying correctly is as follows
<Navbar>
<Navbar.Header>
<Navbar.Brand>
Jobs Ledger
</Navbar.Brand>
</Navbar.Header>
<Nav pullLeft>
<LinkContainer to="/">
<NavItem eventKey={1}>Schedule</NavItem>
</LinkContainer>
<NavDropdown eventKey={2} title="Clients" id="basic-nav-dropdown">
<LinkContainer to="/fetchdata">
<MenuItem eventKey={2.1}>Fetch Data</MenuItem>
</LinkContainer>
</NavDropdown>
<NavDropdown eventKey={6} title="Original" id="basic-nav-dropdown">
<LinkContainer to="/counter">
<MenuItem eventKey={6.1}>Counter</MenuItem>
</LinkContainer>
<LinkContainer to="/fetchdata">
<MenuItem eventKey={6.2}>Fetch Data</MenuItem>
</LinkContainer>
</NavDropdown>
</Nav>
<Nav pullRight>
<LinkContainer to="/">
<NavItem eventKey={1}>Home</NavItem>
</LinkContainer>
<LinkContainer to="/counter">
<NavItem eventKey={2}>Counter</NavItem>
</LinkContainer>
<NavDropdown eventKey={3} title="Dropdown" id="basic-nav-dropdown">
<LinkContainer to="/fetchdata">
<MenuItem eventKey={3.1}>Fetch Data</MenuItem>
</LinkContainer>
</NavDropdown>
</Nav>
</Navbar>
my layout page is as follows:
<div class='container'>
<div>
<NavMenu />
</div>
<div>
{this.props.body}
</div>
</div>
and my page-body (which is up hard against the left side of the screen) is
return (
<div class="container">
<h1>Scheduler goes here!</h1>
</div>
the body should be in line with the navbar...
Set the container to a certain width, for example 50%. Then you can offset this through CSS and the rest of the child elements in the container will have 100% of the 50%.
set the container a fixed width and put a margin in container
.container{
width: 500px;
margin: 0 auto;
}

Resources