I work on a dashboard project at my job and I'm need your help.
React, nextjs and material-ui are used in my application.
On this website, a Menu is defined with clickable links for navigate between page.
However, I can not use correctly <Link> from next/link.
In my application, I need to use <Link/> with something like that:
import Foo from './foo';
[...]
<Link href="/about" passHref>
<Foo />
</Link>
[...]
<Foo/> is defined in another file and contain a <a>.
Even if I pass passHref my link can't be clicked.
In real life, my application is more complicated and use material-ui but the problem seems to be present with this really simplified version : https://gist.github.com/Oyabi/4aea0ce2fa36029868641d147ba9e551
Here the code if gist is down or removed in future:
pages/index.jsx:
import React from "react";
import Menu from "../components/Menu";
function Home() {
return <Menu />;
}
export default Home;
components/Menu.jsx:
import React from "react";
import Link from "next/link";
import MenuItem from "./MenuItem";
function Menu() {
return (
<Link href="/about" passHref>
<MenuItem />
</Link>
);
}
export default Menu;
components/MenuItem.jsx:
import React from "react";
import Link from "next/link";
function MenuItem() {
return (
<div>
<a>not ok - link is not clickable even if the following lines are commented</a>
<br />
<Link href="/about" passHref>
<a>ok - link is clickable</a>
</Link>
<Link href="/about" passHref>
<a>ok - link is clickable</a>
</Link>
<Link href="/about" passHref>
<div className="useless">
foo
<a>even with something more complicated</a>
<br />
<a>the 2 links are clikable</a>
bar
</div>
</Link>
</div>
);
}
export default MenuItem;
If I surround my <a> between <Link> in the same file everything is ok and work as desired but it's not the case if I apply <Link> on a component.
As you can see, even if I setpassHref.
How can I make my <Link> works in Menu.jsx?
Regards.
Try replacing the surrounding div by a fragment like that:
function MenuItem() {
return (
<> // here
<a>not ok - link is not clickable even if the following lines are commented</a>
<br />
<Link href="/about" passHref>
<a>ok - link is clickable</a>
</Link>
<Link href="/about" passHref>
<a>ok - link is clickable</a>
</Link>
<Link href="/about" passHref>
<div className="useless">
foo
<a>even with something more complicated</a>
<br />
<a>the 2 links are clikable</a>
bar
</div>
</Link>
</> // and here
);
}
Related
Im trying to use this package to implement smooth scroll within a Navbar:
https://www.npmjs.com/package/react-scroll
Here's my navbar component:
Navbar.js
import React from "react";
import { Section1, Nav, NavLink, Bars, NavMenu } from "./NavbarElements";
import { Link, animateScroll as scroll } from "react-scroll";
const Navbar = () => {
return (
<>
<Section1>
<Nav>
<Bars />
<Link
activeClass="active"
to="section2"
spy={true}
smooth={true}
offset={-70}
duration={500}
>
Home
</Link>
<Link
activeClass="active"
to="section3"
spy={true}
smooth={true}
offset={-70}
duration={500}
>
Web
</Link>
<Link
activeClass="active"
to="section4"
spy={true}
smooth={true}
offset={-70}
duration={500}
>
Games
</Link>
<Link
activeClass="active"
to="section5"
spy={true}
smooth={true}
offset={-70}
duration={500}
>
About
</Link>
</Nav>
</Section1>
</>
);
};
export default Navbar;
and here's my App.js
App.js
import React from "react";
import "./App.css";
import Navbar from "./components/navbar";
import HomeSection from "./components/home-section";
import WebSection from "./components/web-section";
import GameSection from "./components/games-section";
import AboutSection from "./components/about-section";
function App() {
return (
<>
<Navbar />
<HomeSection id="section2" />
<WebSection id="section3" />
<GameSection id="section4" />
<AboutSection id="section5" />
</>
);
}
export default App;
What am I missing? I thought I ID'd everything correctly but maybe not? Sorry im a noob. Any glaring issues here I'm missing? Is there a better way to implement one page smooth scrolling with react?
https://imgur.com/PvRRMPL
The way react component works that anything you put in the angle bracket its gonna take it as a props here you are not setting up and id you are passing down the prop to your components
<HomeSection id="section2" /> //this is passing props to your homeSection Component
here is how you can fix it:
const HomeSection (props) =>{
return(
<div id={props.id}> //your parent div
</div>
)
or you can wrap it like that
<div id="id="section2"">
<HomeSection />
</div>
If anyone ever sees this and needs a solution, you need to wrap <Element> tags around the component like so:
import { Element } from "react-scroll";
const HomeSection = () => {
return (
<>
<Element id="section2" name="home">
<Section2>
/* CODE */
</Section2>
</Element>
</>
);
};
export default HomeSection;
I am new here but a long time reader of StackOverflow content!
I am new to React and have a simple question about Multi-Pages App.
I did start to work on a website for a friend, I started with a one-pager but finally I did realize that I will need more then only one page. I installed react-router-dom and tried to set it up, the website doesn't return any errors, but only the SideBarMenu component is showing up !
the content of Home is not showing on / , same for the rest on /audio, /video, /images... And the weirdest part of it, if I write as URL for example some random thing like /asiomaos9j, it still show a blank website with the SideBarMenu without even crashing...
Anyone know why all my component on Home are not showing? Or even on /images the js file only contains a div with a H1 inside and this H1 not showing either... I can't figure out what I am doing wrong with this !
I did import as follow:
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
Then here is my App.js :
export default function App() {
return (
<React.StrictMode>
<Routes />
</React.StrictMode>
);
}
My Routes.js :
export default function Routes() {
return (
<Router>
<Switch>
<Route exact path='/' component={Home}></Route>
<Route exact path="/audio" component={AudioPlayerApp}></Route>
<Route exact path="/video" component={VideoPlayerApp}></Route>
<Route exact path="/images" component={ImagesApp}></Route>
</Switch>
<SideBarMenu pageWrapId={"page-wrap"} outerContainerId={"app"} />
</Router>
);
}
Finally as example, here is my Home.js
function Home(){
return(
<React.Fragment>
<Header />
<Services />
<ServicesContent />
<Media />
<MediaContent />
<Studio />
<StudioContent />
<Partenaires />
<PartenairesContent />
<Contact />
<ContactContent />
<Footer />
</React.Fragment>
)
}
export default Home;
Here as asked, SideBarMenu.js :
import React from 'react';
import { slide as Menu } from 'react-burger-menu';
import './components_css/SideBarMenu.css';
export default props =>{
return(
<Menu {...props}>
<a className="menu-item" href="#">
<span>+</span>Accueil
</a>
<a className="menu-item" href="#services_link">
<span>+</span>Services
</a>
<a className="menu-item" href="#media_link">
<span>+</span>Médias
</a>
<a className="menu-item" href="#studio_link">
<span>+</span>Studio
</a>
<a className="menu-item" href="#contact_link">
<span>+</span>Contact
</a>
</Menu>
);
};
These are links inside the Home page for the moment.
Take the exact out of the home route and place it at the end of all others
Below is my code for Cards.js file, right now it's a card that you can click on and it links to the Services page with path ='/services' from within the same website, I would like to add a link to another website, how would I go about doing that? would I need to add an a href= link to Cards.js?
import React from 'react';
import CardItem from './CardItem';
import './Cards.css'
function Cards() {
return (
<div className='cards'>
<h1>Check out my Programming Portfolio Projects!</h1>
<div className='cards__container'>
<div className='cards__wrapper'>
<ul className="cards__items">
<CardItem
src={`${process.env.PUBLIC_URL}/images/ReactSocialPosts.jpg`}
text='hello testing 123'
label='This is a card'
path ='/services'
/>
</ul>
</div>
</div>
</div>
)
}
export default Cards;
Below is CardItem.js if needed
import React from 'react';
import { Link } from 'react-router-dom';
function CardItem(props) {
return (
<>
<li className='cards__item'>
<Link className='cards__item__link' to={props.path}>
<figure className='cards__item__pic-wrap' data-category={props.label}>
<img
src={props.src}
alt='Travel Image'
className="cards__item__img"
/>
</figure>
<div className='cards__item__info'>
<h5 className='cards__item__text'>{props.text}</h5>
</div>
</Link>
</li>
</>
);
}
export default CardItem;
I'm not sure, but I think that you would only have to create a second CardItem with its attribute path = complete link to external website.
Example :
<CardItem
src={`${process.env.PUBLIC_URL}/images/OtherImage.jpg`}
text='External website'
label='A label'
path ='https://externalwebsite.com'
/>
If you just want to simply link to another website then you can simply use an anchor tag, if you want to declare a Route from react-router-dom for that link to follow, you need to look at this post
As per documentation React-Router understands only internal paths. Then an anchor tag is needed. I would do a wrapper component for Link that chose if render an anchor or the router link object. Then use it instead of "Link".
Something like (code not tested):
const MyLink = ({path, children, ...props}) => {
const comp = path?.trim().substring(0,4) === "http" ? <a href={path}> : <Link to={path}>;
return <comp ...props>{children}</comp>
};
I'm using Next.js latest version for making my blog website, don't know why show me error, when I'm trying to make my form then show me error like this:
Warning: Function components cannot be given refs.
Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
I'm tried below code:
import React, { useState } from "react";
import { APP_NAME } from "../config";
import Link from "next/link";
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
NavItem,
NavLink,
} from "reactstrap";
const Header = () => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return (
<div>
<Navbar color="light" light expand="md">
<Link href="/">
<NavbarBrand className="font-weight-bold">{APP_NAME}</NavbarBrand>
</Link>
<NavbarToggler onClick={toggle} />
<Collapse isOpen={isOpen} navbar>
<Nav className="m-auto" navbar>
<NavItem>
<Link href="/signup">
<NavLink style={{ cursor: "pointer" }}>Signup</NavLink>
</Link>
</NavItem>
<NavItem>
<Link href="/signin">
<NavLink style={{ cursor: "pointer" }}>Signin</NavLink>
</Link>
</NavItem>
</Nav>
</Collapse>
</Navbar>
</div>
);
};
export default Header;
please give me your valuable suggestion.
The easiest solution may be to wrap your NavLink with a native html element. In your case:
<Link href="/signup" passHref>
<a>
<NavLink style={{ cursor: "pointer" }}>Signup</NavLink>
</a>
</Link>
From the official documentation: if-the-child-is-a-function-component shows the right way when you wrap a custom function component within Link.
Add passHref attribute in Link.
Wrap your custom function component with React.forwardRef.
However, the NavbarBrand is not a component which you can manipulate. You can create a custom component to wrap NavbarBrand. It probably like
const CustomNavbarBrand = React.forwardRef(({ onClick, href }, ref) => {
return (
<NavbarBrand href={href} onClick={onClick} ref={ref}>
Click Me
</NavbarBrand>
)
})
<Link href="/" passHref>
<CustomNavbarBrand>{APP_NAME}</CustomNavbarBrand>
</Link>
Check the valid property which can be passed to NavbarBrand since I haven't use the reactstrap before.
This worked for me:
<Link href="/">
<div className="navbar-brand">
<a>{APP_NAME}</a>
</div>
</Link>
Instead of using the NavbarBrand component I just added the class navbar-brand
Solution :
Wrapp with anchor tag (a tag)
use passHref attribute
<Link href='/' passHref>
<a>
<Image src='logo.png' width="50px" height="50px" />
</a>
</Link>
Wrapping the child component in an a (anchor) tag resolved my issue.
Steps to reproduce :
Wrap around a component with the Link tag from Next JS
import Link from 'next/link'
import Image from 'next/image'
<Link href="/">
<Image width="100%"
height="100%"
src="/logo.png"
alt="Blitztech Electronics Logo" />
<Link>
Solution :
passing the 'important' passHref attribute
Wrapping the entire children in a a tag
There is a better way to solve this issue: whenever you are going to add a child tag under Link tag, such as an Image tag, just wrap them under a div or a tag. Here is the example:
<Link href="/">
<div>
<Image
src={Logo}
alt={TagName.COMPANY_NAME}
width={80}
height={80}
onClick={handleClicked}
/>
</div>
</Link>
Just Wrap it in anchor tag. it will work fine.
<Link href="/">
<a>{APP_NAME}</a>
</Link>
I'm new to Next.js and I'm trying as per the examples in official docs.
I'm facing an error when trying out the next Layout component.
The layout.js file:
// To style the layout for the entire App
import Head from "next/head";
import Link from "next/link";
import utilStyles from "../styles/utils.module.css";
import styles from "./layout.module.css";
const name = "Aashiq Ahmed";
export const siteTitle = "Next.js Sample Website";
export default function Layout({ children, home }) {
return (
<div className={styles.container}>
<Head>
<Link rel="icon" href="/"></Link>
<meta
name="description"
content="Learn how to build a personal website using Next.js with Aashiq"
/>
<meta
property="og:image"
content={`https://og-image.now.sh/${encodeURI(
siteTitle
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
<header className={styles.header}>
{home ? (
<>
<img
src="/images/profile.png"
className={`${styles.headerHomeImage} ${utilStyles.borderCircle}`}
alt={name}
/>
<h1 className={utilStyles.heading2Xl}>{name}</h1>
</>
) : (
<>
<Link href="/">
<a>
<img
src="/images/profile.png"
className={`${styles.headerImage} ${utilStyles.borderCircle}`}
alt={name}
/>
</a>
</Link>
<h2 className={utilStyles.headingLg}>
<Link href="/">
<a className={utilStyles.colorInherit}>{name}</a>
</Link>
</h2>
</>
)}
</header>
<main>{children}</main>
{!home && (
<div className={styles.backToHome}>
<Link href="/">
<a>Back to home</a>
</Link>
</div>
)}
</div>
);
}
Here I'm trying to pass the 'home' prop to my index.js:
import Head from "next/head";
import Layout, { siteTitle } from "../components/layout";
import utilStyles from "../styles/utils.module.css";
export default function Home() {
return (
<Layout home>
<Head>
<title> {siteTitle} </title>{" "}
</Head>{" "}
<section className={utilStyles.headingMd}>
<p>
{" "}
Hi ,I'm Aashiq , a Enthusiastic Developer who loves to work on Cool
Projects and build great things{" "}
</p>{" "}
<p>
(This is a sample website - you’ ll be building a site like this on{" "}
our Next.js tutorial .){" "}
</p>{" "}
</section>
</Layout>
);
}
Here I'm with 'home' prop rendering the result based on the home prop's presence. I think my syntax is correct but I'm getting this error:
Error: React.Children.only expected to receive a single React element child.
at Object.onlyChild [as only] (D:\Next.js\my-blog\node_modules\react\cjs\react.development.js:1251:13)
at Link (D:\Next.js\my-blog.next\server\pages\index.js:682:33)
at processChild (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:3043:14)
at resolve (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:2960:5)
at ReactDOMServerRenderer.render (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:3435:22)
at ReactDOMServerRenderer.read (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:3373:29)
at renderToStaticMarkup (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:4004:27)
at renderDocument (D:\Next.js\my-blog\node_modules\next\dist\next-server\server\render.js:3:640)
at renderToHTML (D:\Next.js\my-blog\node_modules\next\dist\next-server\server\render.js:52:103)
at async D:\Next.js\my-blog\node_modules\next\dist\next-server\server\next-server.js:76:329
Error: React.Children.only expected to receive a single React element child.
at Object.onlyChild [as only] (D:\Next.js\my-blog\node_modules\react\cjs\react.development.js:1251:13)
at Link (D:\Next.js\my-blog.next\server\pages\index.js:682:33)
at processChild (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:3043:14)
at resolve (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:2960:5)
at ReactDOMServerRenderer.render (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:3435:22)
at ReactDOMServerRenderer.read (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:3373:29)
at renderToStaticMarkup (D:\Next.js\my-blog\node_modules\react-dom\cjs\react-dom-server.node.development.js:4004:27)
at renderDocument (D:\Next.js\my-blog\node_modules\next\dist\next-server\server\render.js:3:640)
at renderToHTML (D:\Next.js\my-blog\node_modules\next\dist\next-server\server\render.js:52:103)
at async D:\Next.js\my-blog\node_modules\next\dist\next-server\server\next-server.js:76:329
My _app.js file:
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
Thanks in advance.