How do you set an 'active' class in React and CSS? - reactjs

I have navigation in my React app. However I would like the colour of navigation to change if on that page.
Heres my code Ive added an active className to the items.
<Link to='/'>
<li className='menu-list-item menu-list-logo active'>Gatsby's</li>
</Link>
<Link to='/drink'>
<li className='menu-list-item active'>Drink</li>
</Link>
<Link to='/food'>
<li className='menu-list-item active'>Food</li>
</Link>
<Link to='contact'>
<li className='menu-list-item active'>Contact</li>
</Link>
The navigation links currently have a background of black. I want the colour to change to lets say red.
P.S I'm using standard CSS for styles.

There is actually a property of activeClassName in NavLink of react router.
It goes like this
Import { NavLink } from 'react-router-dom`
...
<NavLink exact activeClassName="your_active_css_classname" className="normal_css">Link name </NavLink>
Don't forget to add exact. Read more here: https://reacttraining.com/react-router/web/api/NavLink

Light/Fast way to do this would be to change the class at the parent DOM element of these <Link> elements... from there the CSS would do what it works best.
Assuming these <Link> ... </Link> tags are enclosed inside a <nav> ... </nav> tag, which is the parent DOM element.
{ (onThePage) ? <nav className="onThePageClass"> ... </nav> : <nav className="normalClass"> ... </nav> }
Try this else share MVCE if you get stuck so that it serves as a good example for others looking for help

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

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

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

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.

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>

React. Basic example of re-rendering using react-router. +100 rep

I'm newbie. And I'm newbie at React. I'm trying react-router. I saw this example: https://reacttraining.com/react-router/web/example/basic.
I reproduced it on Codesandbox.io here: https://codesandbox.io/s/7jxq0j6qp0
I don't understand why the Menu is re-rendering itself when I change URL using menu's links.
If you open console you can see it.
Why?
I think it should not re-render itself. Just the route section. Where am I wrong?
You can write your component as PureComponent. Since there is no prop changes right now it won't be re-rendered:
class Menu extends React.PureComponent {
render() {
console.log("Menu render() - ", Date.now());
return (
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
</div>
);
}
}
But, please be aware of the negative sides of this method for other use cases: Dealing with Update Blocking

Resources