Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a> - javascript

I'm trying to use react-router with reactstrap with create-react-app.
In the routing page, I needed to use state for the reactstrap, so I converted the router from a variable to a class, but I get this warning:
Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>.
I don't know what to do. I needed to style the router navigation using reactstrap, so I did this:
<NavLink
componentClass={Link}
href="/contact"
to="/contact"
active={location.pathname === '/contact'}
>
anywords
</NavLink>
<Navbar dark id="RouterNavbar" expand="md">
<NavbarBrand id="NavBrand"href="#x">
<ul>
{/* a bunch of <li></li> */}
</ul>
</NavbarBrand>
<NavbarToggler id="NavBarToggler" onClick={this.toggle1.bind(this)} />
<Collapse isOpen={this.state.isOpen1} navbar>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink href="#x"><Link id="RouterNavLink" style={None} to="/contact">anywords</Link></NavLink>
</NavItem>
{/* just more of the above */}
Other than a couple of <li> coming close to each other at random times, hot reloading not working sometimes, and the warning message I get in the console, nothing bad happens, but when I read about this issue, I found out that I shouldn't do this.

This is the code which causing the error,
<NavLink href="#x"><Link id="RouterNavLink" style={None} to="/contact">anywords</Link></NavLink>
Which is converted to,
<a><a></a></a>
So you are getting error,
Warning: validateDOMNesting(…): <a> cannot appear as a descendant of <a>
To solve this just use one of the follow,
<NavLink id="RouterNavLink" style={None} to="/contact">anywords</NavLink>
OR,
<Link id="RouterNavLink" style={None} to="/contact">anywords</Link>

Add the as prop (formerly componentClass) to your original NavLink to keep the styling while also silencing the warning.
See react-bootstrap#nav-link-props docs
Or View Screenshot
Original:
<NavLink href="#x">
<Link id="RouterNavLink" style={None} to="/contact">anywords</Link>
</NavLink>
New:
<Nav.Link as={Link} to="/contact">anywords</Nav.Link>

I would like to suggest an alternate solution which not only solve your problem but give you desired result. In any case someone else stumbled on this post like I did.
Use Link jsx element offered by react router dom but add className="nav-link" to it. This will give you styling of the NavLink jsx which react strap is using.
So, it should look like this,
<Link className="nav-link" id="RouterNavLink" style={None} to="/contact">anywords</Link>

you can try this in order to avoid the error
<NavItem as="li"> <Link>.....

I had same problem. It is because we can not use link, or a tag inside another like...
<a><a></a></a>
I wanted to apply className to my a tag in navigation bar. so i applied className to a tag in component and import that component in navigation bar component
<a className="nav-link" onClick={() => loginWithRedirect()}>
Login
</a>
This is how i use this link in navigation template,without any classname
<LoginButton />

Related

Nav Menu Active Element and State Management Issue

I am trying to show an active <Nav.Link> element for the current page, but it keeps getting reset when I go between pages to the default value. Each of the links goes to a different route I have defined in React-Router. I am trying to use jotai for state management to store the value of the current page, but am not able to get the correct value to display.
For example, the code below has pills to show the active selection in the nav. I want to be able to do this even when I go to a different page since this is the nav menu.
import Nav from 'react-bootstrap/Nav';
function TabsExample() {
return (
<Nav variant="pills" defaultActiveKey="/home">
<Nav.Item>
<Nav.Link href="/home">Active</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-1">Option 2</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="disabled" disabled>
Disabled
</Nav.Link>
</Nav.Item>
</Nav>
);
}
export default TabsExample;
However, I believe my page keeps re-rendering/reloading (goes white for a brief second) for some reason whenever I go to a different page.
There might be something I'm not getting, so please let me know.
The issue here is likely that the Nav.Link component renders an anchor <a> element by default and this is causing the page to reload when you click the links. You can specify each Nav.Link to render the NavLink (or Link) component exported from react-router-dom so that clicking links will now correctly be handled by RRD. Specify a to prop instead of an href prop, and set the eventKey prop to match the link target so the "pill" state can work as well.
Example:
import { NavLink } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import Nav from "react-bootstrap/Nav";
function PillsExample() {
return (
<Nav variant="pills">
<Nav.Item>
<Nav.Link as={NavLink} end to="/" eventKey="/"> // * Note on end prop
Home
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link as={NavLink} to="/foo" eventKey="/foo">
Foo
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link as={NavLink} to="/bar" eventKey="/bar">
Bar
</Nav.Link>
</Nav.Item>
</Nav>
);
}
* Note: If the end prop is used, it will ensure this component isn't matched as "active" when its descendant paths are matched. See NavLink for more component details.

DOM disappearing when replacing anchor tags with React Link components

I am new to working on the frontend. I'm learning how to use React and react-router-dom library. The program renders without a problem normally. The problem lies when I try to add a Link component from the React library. When I do this, the DOM is no longer displayed.
import React from "react"
import {Routes, Route, Link} from "react-router-dom"
import Mflix from "./components/mflix.js"
function App(){
return (
<div className="App">
<nav className="navbar navbar-expand navbar-dark bg-dark">
<a href="/mflix" className="navbar-brand"> {/*href links to "/mflix" route */}
Mflix Reviews
</a>
<div className="navbar-nav mr-auto">
<li className="nav-item">
<Link to={"/mflix"} className="nav-link">
Movies
</Link>
</li>
</div>
</nav>
</div>
)
}
This SO forum has a similar problem, except they created a class for their app, and I'm trying to keep it as a function for now.
If I replace the code:
<Link to={"/mflix"} className="nav-link">
Movies
</Link>
with
<a href="/mflix"m className="nav-link">
Movies
</a>
The DOM renders fine, buT I want to use Link because it doesn't force my page to refresh every time.
Edit: I read that instead of passing a JS expression to the to <Link to{"/mflix"}/> I should pass a string <Link to"/mflix"/>. However, the documentation says that if the link uses a path name, then it should be passed to to= as an object, and not a string. IN any case, I tried the suggestion, but the code still returns a blank page.
Edit: This is what the web console has to say about the component:
he above error occurred in the <Link> component:
LinkWithRef#http://localhost:3000/static/js/bundle.js:37314:9
li
div
nav
div
App#http://localhost:3000/static/js/bundle.js:40:72
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
Whenever the DOM disappears, there is an issue in your code. I'm guessing it has to do with this "Mflix" import. Bring up the console and see what it says.

Menu does not collapse when you click on one of the menu items on Mobile Devices

Hi All i need some help :)
I working on a Gatsby, React portfolio where i have a problem with The Menu It does not collapse when you click on one of the menu items on Mobile Devices.
The menu is working fine on desktop.
The menu works fine on all devices until I installed the react-scroll package and set it up.
I have tried to search on Google for help and i found some simlare issues but i still dont know to fix the problem. :)
Hope you can help.
There is to Nav components i my project:
This my Project on SandBox:
NavBar.js
https://codesandbox.io/s/gatsby-starter-and-portfolio-jr9tn?file=/src/components/Navbar/Navbar.js
NavbarLinks:
https://codesandbox.io/s/gatsby-starter-and-portfolio-jr9tn?file=/src/components/Navbar/NavbarLinks.js
Here you have your CodeSandbox fixed: https://codesandbox.io/s/gatsby-starter-and-portfolio-forked-43thz?file=/src/components/Navbar/NavbarLinks.js
What was happening is that, since you've installed react-scroll, the state was never updated when an item was selected so, React's rehydration was never occurring and your menu was never closed. The code is a bit redundant however I've managed to get it to work. What I've added is a simple function passed via props that toggle the menu.
In your NavBar.js, instead of:
<Toggle
navbarOpen={navbarOpen}
onClick={() => setNavbarOpen(!navbarOpen)}
>
If added a function, since it's not a good practice to trigger effects directly bonded in the components. I've changed it to:
<Toggle navbarOpen={navbarOpen} onClick={toggleMenu}>
That toggleMenu function, is a simply function that does the same than your previous one:
const toggleMenu = () => setNavbarOpen(!navbarOpen)
Now, you have isolated that piece of functionality and you can reuse it, passing it to your child component (NavbarLinks):
{navbarOpen ? (
<Navbox>
<NavbarLinks toggleMenu={toggleMenu} />
</Navbox>
) : (
<Navbox open>
<NavbarLinks toggleMenu={toggleMenu} />
</Navbox>
)}
Note: this code is redundant, should be refactored to avoid that kind of unnecessary repetition. For example, something like this is much better:
<Navbox open={navbarOpen}>
<NavbarLinks toggleMenu={toggleMenu} />
</Navbox>
As you can see, you <NavbarLinks> have the functionality to toggle the menu in toggleMenu function so there you can trigger the function in every click (onClick):
const NavbarLinks = ({ toggleMenu })=> {
return (
<>
<NavItem
activeClass="active"
to="section1"
spy={true}
smooth={true}
duration={1000}
onClick={toggleMenu}
>
About
</NavItem>
<NavItem
activeClass="active"
to="section2"
spy={true}
smooth={true}
duration={1000}
onClick={toggleMenu}
>
Test
</NavItem>
<NavItem
activeClass="active"
to="section3"
spy={true}
smooth={true}
duration={1000}
onClick={toggleMenu)}
>
Gallery
</NavItem>
<NavItem to="/page-2">Contact</NavItem>
</>
)
}
Since you are destructuring props, you have the toggleMenu function available directly.

Next.js: Error: React.Children.only expected to receive a single React element child

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>
</>
);
}

react bootstrap dropdown doesn't close when react router link gets called

<NavDropdown
className="userDropdownButton"
title="dropdown"
id="user-nav-dropdown"
alignRight
>
<div className="userDropDown">
<Link to="/user" className="userDropDownheader">
user
</Link>
</div>
</NavDropdown>
And both - the dropdown and the <Link> work just fine, but the dropdown doesn't close when I click on the link. I tried using https://github.com/react-bootstrap/react-router-bootstrap but it didn't fix my issue. Are there some other things I could try?
npm install react-router-bootstrap
then in your nav page :
import { LinkContainer } from "react-router-bootstrap";
<NavDropdown title='Dropdown' id='responsive-navbar-nav'>
<LinkContainer to='/views/Page4' >
<NavDropdown.Item>Counter</NavDropdown.Item>
</LinkContainer>
</NavDropdown>
Im using https://react-bootstrap.github.io/components/navbar/
Hope you can use LinkContainer to solve your problem.

Categories

Resources