Warning: validateDOMNesting(…): <a> cannot appear as a descendant of <a> - reactjs

I'm using React router dom Link component. It is basically twitter's home feed. I want to be able to have two type of Links in one div component. One will be Link to go to user's profile and other one to go to post. I am currently getting warning and couldn't find solution for now. Here is the screenshot as reference:
I understand the issue here, my post Link is the parent element and I've added two user Link components inside of it as the user should be able to access post page when he clicks on anything inside of the post except user's profile photo and user's name. Is there any smarter way of achieving this and keeping links like this?
Code:
{posts?.map((post) => (
<Link
className={classes.link}
key={post.user.id}
to={`/posts/${post.id}`}
>
<div className={classes.post}>
<Link to={`/users/${post.user.id}`}>
<img
className={classes.profileImage}
src={DefaultLogo}
alt="default-profile"
/>
</Link>
<article className={classes.postDetails}>
<Link
className={classes.link}
to={`/users/${post.user.id}`}
>
<Typography
variant="subtitle1"
className={`${classes.postTitle} ${classes.content}`}
>
{post.user.name}
</Typography>
</Link>
<Typography
variant="subtitle1"
className={`${classes.postText} ${classes.content}`}
>
{post.body}
</Typography>
</article>
</div>
</Link>
))}

Yes, having anchor tags inside of another anchor tag is misleading a bad approach to doing things. But given your requirements you can make use of a basic button with react router dom history api.
A simple example:
import {Link, useHistory} from 'react-router-dom'
const App = () => {
const history = useHistory()
return (
<a
href='/user/1'
>
<h2>John doe</h2>
<div>here are some use information</div>
{/* Need to prevent the event bubbling */}
<Link role='link' to='/users/1/posts'>
User posts
</Link>
</div>
)
}

Related

Link component error with multiple childe elements when there are none [duplicate]

I'm having a component called Nav inside components directory and it's code is some thing like below:
import Link from 'next/link';
const Nav = () => {
return(
<div>
<Link href="/"> <a> Home </a> </Link>
<Link href="/about"> <a> About </a> </Link>
</div>
)
}
export default Nav;
This gives me the error:
Error: React.Children.only expected to receive a single React element child.
But if I remove the <a> tags within <Link> components, I can view the pages, but then in the console I'm getting a warning of:
Warning: You're using a string directly inside <Link>. This usage has been deprecated. Please add an <a> tag as child of <Link>
So what am I doing wrong here?
This issue is due to the space between <Link> tag and <a> tag.
So change your code like,
<div>
<Link href="/"><a> Home </a></Link>
<Link href="/about"><a> About </a></Link>
</div>
Reason for the change:
-> The <Link> can have only one child node and here the space between the link and a tag are considered as a child nodes.
-> So there are two child nodes (One is space and another is <a> tag) which is invalid and hence such error occurs.
Space between < Link > and < a > makes you error "Unhandled Runtime Error
Error: Multiple children were passed to with href of / but only one child is supported https://nextjs.org/docs/messages/link-multiple-children
Open your browser's console to view the Component stack trace."
Remove the space and it work fine.
import Link from "next/link";
const NavBar = () => {
return (
<nav>
<Link href="/"><a>Home </a></Link>
<Link href="/About"><a>About </a></Link>
<Link href="/Contact"><a>Contact </a></Link>
</nav>
)
}
export default NavBar
I had the same issue as I was doing:
<Link href={`/tutorial/${tutorial.slug}`}>{tutorial.title}</Link>
The fix was to wrap it in an a tag:
<Link href={`/tutorial/${tutorial.slug}`}><a>{tutorial.title}</a></Link>
If the child is <a> tag then add legacyBehavior. it will work
import Link from 'next/link'
function Legacy() {
return (
<Link href="/about" legacyBehavior>
<a>About Us</a>
</Link>
)
}
export default Legacy
I had a space that was considered as an undefined component
<Link href={to}><a className={'abc'}>{children}</a> </Link>
Removing the space, it was ok. 30 minutes lost only, thanks to experience and internet help.
I was having the same issue there were no problems with spaces rather I was passing an integer inside Link
<Link href={{
pathname: `/dashboard/people`,
query: { idPerson: 123 }}}>
{123}
</Link>
I resolved this error by parsing the integer using toString() method
<Link href={{
pathname: `/dashboard/people`,
query: { idPerson: 123 }}}>
{(123).toString()}
</Link>
Check if inner content is empty
In addition to the scenarios covered by other answers, this error also gets fired when there's no content in between <Link> opening and closing tags.
For example:
<Link href='/'></Link> // i am an error
Im following the NextJs tutorial and space is not only the culprit. Semi colon also.
// without space, this will also not work because of the semi-colon
function FirstPost() {
return (
<>
<h1> First Post </h1>
<h2>
<Link href="/">
<a>Back to Home</a>;
</Link>
</h2>
</>
);
// with space but without semi-colon will not also work
function FirstPost() {
return (
<>
<h1> First Post </h1>
<h2>
<Link href="/">
<a> Back to Home </a>
</Link>
</h2>
</>
);
}

How to display React-Bootstrap's NavDropdown on Hover

Related to this question, whose top answers no longer work. By default, the NavDropdown only appears when clicked on, however I need this dropdown to display on hover. I struggled loading 'React-Bootstrap' into stackoverflow to create a reproducible example, however here is a basic Navbar using react-bootstrap, that features my attempt to display the dropdown on hover:
const [isStatsOpen, setIsStatsOpen] = useState(true);
<Navbar>
<Navbar.Brand>
<Link to='/'>
<img alt='company logo' src={My Logo} />
</Link>
</Navbar.Brand>
<Navbar.Toggle aria-controls='basic-navbar-nav' />
<Navbar.Collapse id='basic-navbar-nav'>
<Nav className='mr-auto'>
<NavDropdown title='Statistics'
onMouseEnter={() => setIsStatsOpen(true)}
onMouseLeave={() => setIsStatsOpen(false)}
open={isStatsOpen}
>
<NavDropdown.Item as={Link} to='/stats/'> Stats 1</NavDropdown.Item>
<NavDropdown.Item as={Link} to='/stats2/'>Stats 2</NavDropdown.Item>
</NavDropdown>
</Nav>
<Nav className='ml-auto'>
<DivisionSelect />
<AppSelect />
</Nav>
</Navbar.Collapse >
</Navbar >
From the linked post above, there were 2 responses with 10+ votes, however neither of these solutions work. As it pointed out in one of the comments: This doesn't work in newer versions, the dropdown isn't rendered until it's first click. You'd need to trigger the onclick before you could control via css.
After inspecting the page, I can confirm that this person is correct - there is no menu for which to display until after the NavDropdown has been clicked upon. Once clicked, the menu is there, and then the solutions from this other post do work. Given this as the case, how can I resolve this issue? Is it possible for my react component to automatically "click" the Navdropdowns on load, that way the menus will appear on hover?
Thanks!
Does this help you? Old good vanilla javascript.
I added an id at NavDropdown and called the old, classic document.getElementById method and then triggered the click event.
useEffect(() => {
document.getElementById("test").click();
}, []);
<NavDropdown
id="test"
title="Statistics"
https://codesandbox.io/s/react-bootstrap-demo-z36c5
In this link to the earlier version of the question, the highly voted answer that starts with export class Nav extends React.Component { does work, so long as the open prop is updated to show.

React Router not loading specific component and removing all other components too

I'm learning the basics of React Router. So what I'm making right now has a navigation bar on top and two buttons below this top bar. What I want is for the a table or something of the sort to show up when I press one of the buttons.
The problem is that when I click the button, the URL changes but the all the components vanish. Even the component I want displayed doesn't show and the other components (which ideally should stay) also disappear.
What am I doing wrong here? The code is as follows :-
const Site = () =>
<React.Fragment>
<div className="container-fluid row">
<div className="offset-3 col-sm-4">
<Link to="/A">
<Button value="A"/>
</Link>
</div>
<div className="col-sm-4">
<Link to="/B">
<Button value="B"/>
</Link>
</div>
</div>
<div>
<Route path="/B" component={B}/>
</div>
</React.Fragment>
export default Site;
The Site page has the URL '/Site'.
Edit:
Just thought I'd mention the structure a bit. So for now I have a page with a button. Clicking this button should load the a component (called Base with URL '/Site') which is calling the TopBar and Site components.
Then I have these two buttons - A and B which have their respective URLs.

Unable to make React Router Dom Link to work

In my react component, PostItem, I've created a pointing to edit post page. All the works in my other components, except this one, and I could not find out why.
The page is successfully rendered with tag and proper href address, but I can't click the link. In fact, none of tags or link works on this component.
I have tried to create direct and link to any external site, but all links seem to be disabled on this component.
const PostItem = ({ id, title}) => (
<div className="list-item prfx-color" key={id}>
<div className="list-header">
<h3 className="list-title">{title}</h3>
<Link to={`/EditPost/${id}`}>
<i className="material-icons" style={{ color: 'white' }}>edit</i>
</Link>
</div>
</div >
)
I expect links to be clickable.
I found the reason why the or any not working. It has nothing to do with React-Router-Dom. It's my sass, where parent has a attribute of "position: absolute" and "z-index: -1".
When working with z-index and position, it would disable all links on the page. So, what I did was simple delete the position attribute.

click an image for outside url react.js

I am working on a portfolio and I'm using react.js. I simply want to click an image, for example, a StackOverflow icon, and be able to redirect to the page. I'm seeing all sorts of different ways to go about, yet I cannot get it to redirect.
I am using React-Bootstrap which I don't know if that is going to change anything.
export default class Home extends Component {
render() {
return (
<Grid>
<Jumbotron className="brainImg">
</Jumbotron>
<div class="footer"><center className="iconsBaby">
<Image src="giticon.png" className="githubIcon" to="https://github.com/Joeyryanbridges" />
<Image src="linkedinIcon.png" className="linkedinIcon" href="https://github.com/Joeyryanbridges" />
<Image src="SOFIcon.png" className="githubIcon" href="https://github.com/Joeyryanbridges" />
</center>
</div>
</Grid>
)
}
Thank you for looking.
Generally an Image component should not be a link on its own. What you should do is wrap your image component with an <a> tag or use the Link component if you're using react-router.
<a href="https://github.com/Joeyryanbridges">
<Image src="giticon.png" className="githubIcon" />
</a>
OR with react-router Link
<Link to="https://github.com/Joeyryanbridges">
<Image src="giticon.png" className="githubIcon" />
</Link>
This way the Image component is not concerned with redirects or changing URLs and that functionality is handled by the proper component or tag.
Always keep in mind that separation of concerns is very important when it comes to reusability and maintainability.
Just wrap tag inside an like this:
<a href="abc.com">
<Image src="abc.png" />
</a>
Or If you are using react-router,then you can do this:
import { Link } from "react-router-dom";
<Link to="www.abc.com">
<Image src="abc.png" />
</Link>
Hope this help:
1.You can first declare in the state
load:false
2.use the onClick event and call a function like -
<Image src="giticon.png" className="githubIcon" onClick={()=> handleClick()} />
Inside the function set load to true.
Now check the value of the load to direct to whatever you need.
I hope it works.
There is another method to it , which is just create a onclick attribute to your react element
<img src="<img-link>" alt="<alt-text>" onClick={link} />
and then outside the return statement of your react function you can use 2 methods to link the image which is
location.replace and location.href
both of which would have syntax as follow
window.location.href = "<link>";
and
window.location.replace("<link>");
the methode to use this both is as follow
const link= () => { //remember the onclick attribute mentioned in img tag is having name **link**
window.location.href = "<the-link-to-which-you-want-to-redirect";
}
in this way you can achive your desired output!!
line 6 contain the function and line 18 contain styled react image element... refer if you want
Note:-
window.locatio.replace("")
will replace the webpage , so some one clicking on the image would not be able to use back button of browser .
So use them according to your need!!
The easiest way I've found is to just make sure you add target="_blank" rel="noopener noreferrer" to your tag. Like this:
<a href={ resume } target="_blank" rel="noopener noreferrer">
<img className="resume" src={ resumeLogo } alt="Link to resume" />
</a>
To use an image as a link in React, wrap the image in an tag or a Link tag if using react-router. The image will get rendered instead of the link and clicking on the image will cause the browser to navigate to the specified page.
import {Link} from 'react-router-dom';
The function code can be as follows:
<div>
<Link to="/your-pagename-or-url">
<img src="https://hamedvahedi.com/sample.jpg" alt="" />
</Link>
</div>

Resources