Im learning now the ReactJS and I read a lot of topics about this article, but I can't find a right solution for my problem.
I want to add a active class to li item not a, like
<li class="active">Item</li>
not
<li>Item</li>
This is my reactJS code
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, Redirect, Switch } from "react-router-dom";
const Content = () => (
<Router>
<div className="content">
<div className="navigation">
<ul>
<li>
<Link to="/app">Wallets</Link>
</li>
<li>
<Link to="/backup">Backup</Link>
</li>
<li>
<Link to="/keys">Private keys</Link>
</li>
<li>
<Link to="/security">Security</Link>
</li>
<li>
How it works
</li>
</ul>
</div>
<div className="wrapper">
<Switch>
<Route path="/app" component={App} />
<Route path="/backup" component={Backup} />
<Route path="/keys" component={Keys} />
<Route path="/security" component={Security} />
<Redirect to="/app" />
</Switch>
</div>
</div>
</Router>
);
...
export default Content;
You can use NavLink, it has a property for the active Links:
import { NavLink } from 'react-router-dom';
After:
<ul>
<li>
<NavLink to="YOUR_ROUTE" exact activeClassName="link-active">
{ YOUR_CONTENT }
</NavLink>
</li>
</ul>
Now your links which are actives will have link-active class name.
activeClassName
The className a receives when its route is active. No active class by default.
https://knowbody.github.io/react-router-docs/api/Link.html
Related
when using react-router-dom, I cannot render any of my components or anything.
All it does is show a white screen, it doesn't add anything to my index.html template.
There aren't any errors however it says that in index.js there are unused variables that are my components.
Heres my code:
index.js
// Imports
import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.css';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { navbar, footer, home } from './components';
ReactDOM.render(
<Router>
<navBar />
<Routes>
<Route path="/" element={<home />} />
</Routes>
<footer />
</Router>,
document.getElementById("root")
);
home.jsx
import React from "react";
function home(){
return(
<div className="home">
<div class="container">
<div class="row allign-items-center my-5">
<div class="col-lg-7">
<img class="img-fluid rounded mb-4 mb-lg-0" src="./img/pizza.jpg" alt=""/>
</div>
<div class="col-lg-5">
<h1 class="font-weight-light">cencored</h1>
<p>cencored</p>
</div>
</div>
</div>
</div>
)
}
export default home;
navBar.jsx
import React from 'react';
import {NavLink} from 'react-router-dom';
function navBar(){
return(
<div className="navBar">
<nav className="navbar navbar-expand navbar-dar bg-dark">
<div className="container">
<NavLink className="navbar-brand" to="/"><img src="../img/logo.png" alt="logo" style="width:500px;height:500px;"/></NavLink>
<div>
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<NavLink className="nav-link" to="/menu">Menu</NavLink></li>
<li className="nav-item">
<NavLink className="nav-link" to="/about">About</NavLink></li>
<li className="nav-item">
<NavLink className="nav-link" to="/contact">Contact</NavLink></li>
</ul>
</div>
</div>
</nav>
</div>
);
}
export default navBar;
footer.jsx
import React from 'react';
import {NavLink} from 'react-router-dom';
function footer(){
return(
<div className="footer">
<footer class="py-5 bg-dark fixed-bottom">
<div class="container">
<p class="m-0 text-center text-white">cencored</p>
</div>
<div>
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<NavLink className="nav-link" to="/">Home</NavLink></li>
<li className="nav-item">
<NavLink className="nav-link" to="/menu">Menu</NavLink></li>
<li className="nav-item">
<NavLink className="nav-link" to="/about">About</NavLink></li>
<li className="nav-item">
<NavLink className="nav-link" to="/contact">Contact</NavLink></li>
</ul>
</div>
</footer>
</div>
);
}
export default footer;
index.js (component exports)
export { default as navbar } from './navBar';
export { default as footer } from './footer';
export { default as home } from './home';
Instead of using the element prop on your Route try to component prop like
<Route path="/" component={Home}>
You also must capitalize components.
React components should use PascalCase names.
export { default as Navbar } from './navBar';
export { default as Footer } from './footer';
export { default as Home } from './home';
...
import { Navbar, Footer, Home } from './components';
ReactDOM.render(
<Router>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
</Routes>
<Footer />
</Router>,
document.getElementById("root")
);
You are missing import of Switch from 'react-router-dom' and after you have to wrap your Routes into . And into Routes you have to add all of your components with path not only Home component.
Pseudo code:
import { Switch, Route, Router } from "react-router-dom";
import Home from '.....path'
//import all routing componets
const Routes = () => {
return(
<Switch>
<Route exact path='/' component={Home}>
<Route exact path='/comp1' component={Comp1}>
<Route exact path='/comp2' component={Comp2}>
</Switch>)}
const App = () => {
<Router>
<GlobalNav />
<Container fluid={true}>
<SideNav />
<Routes />
</Container>
</Router>}
Then you can add your navbar anywhere but has to be wrapped into router. I just added as example i can have a typo somewhere but if you follow the concept it should work. And change your components to Pascal naming.
I'm actually kinda new to React, and I'm still learning, so I cannot figure out how to display my button depending on which page I currently am on my app.
I'm using Router v6.
This is my Router with my components inside:
<Router>
<Navbar />
<Routes>
<Route
path="/"
element={<HomePage />} />
<Route
path="/CountryPage"
element={<CountryPage />} />
</Routes>
</Router>
This is my navbar:
const Navbar = () => {
return (
<nav className="navbar-container">
<div>
<div>
<ul className="navbar">
<li>
<Link to="/" className="home"> <AiOutlineLeft /> </Link>
</li>
<li data-testid="tab-name">
Current Tab
</li>
<li>
<BsFillGearFill className="settings" />
</li>
</ul>
</div>
</div>
</nav>
);
};
So all I want is to display the button that is <li> <Link to="/" className="home"> <AiOutlineLeft /> </Link> </li> only if I am not in the HomePage So if I am in the Homepage I don't want to show anything.
Any idea?
window.location.href is a out-of-the-box JS method you should use if you don't have your routing managed by some better library (like react router). Also, here, instead of just the pathname, you actually have to check the entire URL.
So your corrected code for this method would be
{ window.location.href !=== "yoursubdomian.yourdomain.extension/" && <li> <Link to="/" className="home"> <AiOutlineLeft /> </Link> </li>
My advice would be that try a systematic approach using the provisions React Router itself provides
Use the useLocation() hook to extract the pathname of the current route and check it for rendering the <Link/>
const Navbar = () => {
const location = useLocation()
return (
<nav className="navbar-container">
<div>
<div>
<ul className="navbar">
{location.pathname !=="/" &&
<li>
<Link to="/" className="home"> <AiOutlineLeft /> </Link>
</li>
}
<li data-testid="tab-name">
Current Tab
</li>
<li>
<BsFillGearFill className="settings" />
</li>
</ul>
</div>
</div>
</nav>
);
};
Thank you for opening this page in advance.
I am a self-taught coder. And now I am making my personal page with Bootstrap.
What I want to do now is; SPA feature of React.js. All I understand this feature is;
install "react-router-dom",
import { Link, NavLink } from "react-router-dom";
And replace those anchor and href tag to Link to=
The following code is in 'src' folder.
Navbar.js
import React from "react";
import logoImage from "../components/logo.png";
// React fontawesome imports
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faBars } from "#fortawesome/free-solid-svg-icons";
import { Link, NavLink } from "react-router-dom";
const Navbar = () => {
return (
<nav className="navbar navbar-expand-lg navbar-light bg-white">
<div className="container-fluid">
<a className="navbar-brand mr-auto" href="#"><img className="logo" src={logoImage} alt="logoImage"/></a
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<FontAwesomeIcon icon={faBars} style={{ color: "#2ff1f2" }}/>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<a className="nav-link active" aria-current="page" href="../components/About">About me</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Thoughts</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Portfolio</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Contacts</a>
</li>
</ul>
</div>
</div>
</nav>
)
}
export default Navbar;
App.js
import './App.css';
import "bootstrap/dist/css/bootstrap.min.css";
import Button from "react-bootstrap/Button";
import Particles from "react-particles-js";
import Navbar from "./components/Navbar";
import Header from "./components/Header";
import About from "./components/About";
function App() {
return (
<>
<Particles
className="particles-canvas"
params={{
particles: {
number: {
value: 30,
density: {
enable: true,
value_area: 900
}},
shape: {
type: "star",
stroke: {
width: 6,
color: "#f9ab00"
}}}}}
/>
<Navbar />
<Header />
<About />
</>
);
}
export default App;
Header.js
import React from "react";
import Typed from "react-typed";
import { Link } from "react-router-dom";
const Header = () => {
return (
<div className="header-wraper">
<div className="main-info">
<h1>Welcome, this is my own personal page</h1>
<Typed
className="typed-text"
strings={["text message to display in the centre of the page"]}
typeSpeed={80}
/>
Details
</div>
</div>
)
}
export default Header;
And soon as I replace
<a className="nav-link" href="#">Thoughts</a>
to
<Link to="../components/About">Thoughts</Link>
It stops working with this following error message.
×
Error: Invariant failed: You should not use <Link> outside a <Router>
invariant
C:/Users/Administrator/my-portfolio/node_modules/tiny-invariant/dist/tiny-invariant.esm.js:10
(anonymous function)
C:/Users/Administrator/modules/Link.js:88
85 | return (
86 | <RouterContext.Consumer>
87 | {context => {
> 88 | invariant(context, "You should not use <Link> outside a <Router>");
| ^ 89 |
90 | const { history } = context;
91 |
My understanding to this error is:
I should make Router.js file in src folder.
I should just start again without Bootstrap first. Once SPA feature is done, then I can start work on this CSS feature as CSS in JS (e.g. const something = div.styled ``;)
I know this sounds ridiculous, but this is the best option I could think for now.
Question is, Where should I begin investigating this error message?
I am currently relying on this document page to remove the error message.
1st Example: Basic Routing - https://reactrouter.com/web/guides/quick-start
I would appreciate your opinion. Thank you.
If I found a solution, I will update it with mine here.
This is a good question, but, in order to answer it the best way, you will need to work with several files, as I'm sure you're already aware of.
To start, assuming you used create-react-app, go to the index.js file, and wrap everything from the first parameter with react-router-dom's BrowserRouter component. It should look like the following:
index.js
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>,
document.getElementById("root")
);
Next, you will want to use react-router-dom's Switch component to wrap all the application's routes.
App.js
import { Route, Switch } from "react-router";
import Navbar from "./components/Navbar";
import Header from "./components/Header";
import About from "./components/About";
// Particles component removed for explanation
function App() {
return (
<Navbar />
<Header />
// When a link is clicked, the component will appear within the following div,
// so if you want certain elements to stay where they are on the page, wrap
// and place the Switch component accordingly.
<div className='pages'>
<Switch>
<Route path='/about' component={About} />
<Route path='/profile' component={profile} />
<Route path='/thoughts' component={Thoughts} />
<Route path='/contacts' component={Contacts} />
</Switch>
</div>
);
}
export default App;
Now, within any child component of App, you can use react-router-dom Links (I personally prefer using NavLink due to its ease of styling). This could be done by the following:
Navbar.js
import { NavLink } from "react-router-dom";
const Navbar = (props) => {
return (
<nav className="navbar navbar-expand-lg navbar-light bg-white">
<div className="container-fluid">
<NavLink className="navbar-brand mr-auto" to='/home'>
<img className="logo" src={logoImage} alt="logoImage"/>
</NavLink
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<FontAwesomeIcon icon={faBars} style={{ color: "#2ff1f2" }}/>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<NavLink className="nav-link active" to='/about'>About me</NavLink>
</li>
<li className="nav-item">
<NavLink className="nav-link" to='/thoughts'>Thoughts</NavLink>
</li>
<li className="nav-item">
<NavLink className="nav-link" to='/portfolio'>Portfolio</NavLink>
</li>
<li className="nav-item">
<NavLink className="nav-link" to='/contacts'>Contacts</NavLink>
</li>
</ul>
</div>
</div>
</nav>
)
};
export default Navbar;
After doing what is shown below, you will be able to navigate throughout your page using react-router-dom.
Router is a component provided by react-router-dom As the error says, Link can be used inside Router.
Also, path for Link should actual browser url and not the path of the component. Ideal way is to add routes for each component.
For Example your App can be like this: (Only for reference)
function App() {
return (
<Router>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/">
<Navbar />
</Route>
</Switch>
</Router>
);
}
Yes, you can do that, this error happen since you are missing to wrap <Link> component via <Router>...
If you like to put it for all project, you can simply do this:
<Router>
<App />
</Router>
Example:
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
I am building a portfolio website and am using react BrowserRouter, Link and Switch to manage my websites routing My problem is that when I click on the 'Projects' link it changes on url but not in view, however when I refresh the page it works.
here is what my routing currently looks like in my App.js.
import React, { Component } from 'react';
import NavBar from './Components/NavBar/NavBar'
import Home from './Components/Home/Home';
import Projects from './Components/Projects/Projects';
import { BrowserRouter ,Switch, Route, } from 'react-router-dom';
class App extends Component {
render() {
return (
<div className="App">
<NavBar />
<BrowserRouter>
<Switch>
<Route path="/" component={Home} exact={true} />
<Route path="/projects" component={Projects} />
</Switch>
</BrowserRouter>
</div>
);
}
}
export default App;
and this is what my Navbar.js looks like..
import React, {useState} from 'react';
import { NavLink, BrowserRouter } from 'react-router-dom'
import { Link } from 'react-scroll';
function NavBar() {
const [navbar,setNavbar] = useState(false)
const changeBackground = () => {
if(window.scrollY >= 100) {
setNavbar(true)
} else {
setNavbar(false)
}
}
window.addEventListener('scroll', changeBackground)
return(
<BrowserRouter>
<ul className="nav bg-white sticky-top nav-tabs nav-justified">
<li className="nav-item">
<Link
className={navbar ? "nav-link text-dark home" : "nav-link text-secondary home"}
to="home"
href="/"
smooth={true}
offset={50}
duration={500}>
Home
</Link>
</li>
<li className="nav-item">
<Link
className={navbar ? "nav-link text-dark home" : "nav-link text-secondary about"}
to="about"
smooth={true}
offset={50}
duration={500}>
About
</Link>
</li>
<li className="nav-item">
<NavLink to="/projects">Projects</NavLink> //This is the link that won't work.
</li>
<li className="nav-item">
<Link
className={navbar ? "nav-link text-dark home" : "nav-link text-secondary contact"}
to="contact"
smooth={true}
offset={50}
duration={500}>
Contact
</Link>
</li>
</ul>
</BrowserRouter>
)
}
export default NavBar
Any help would be great!
The problem is that you're defining two different BrowserRouter. All your routing logic should be under one BrowserRouter:
App should be like this:
class App extends Component {
render() {
return (
<div className="App">
<BrowserRouter>
<NavBar />
<Switch>
<Route path="/" component={Home} exact={true} />
<Route path="/projects" component={Projects} />
</Switch>
</BrowserRouter>
</div>
);
}
}
and NavBar should not have the wrapping BrowserRouter
In the context of the DOM how do I change the order of how the links for a react router setup?
See the following example:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import 'bootstrap/dist/css/bootstrap.css';
import Counter from './components/counter';
import Counters from './components/counters';
import ColorPicker from './components/colorpicker';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
ReactDOM.render(
<main className="content-area">
<Router>
<Route path="/counter" component={Counter} />
<Route path="/color-picker" component={ColorPicker} />
<ul>
<li>
<Link to="/">Main Page</Link>
</li>
<li>
<Link to="/counter">Counter</Link>
</li>
<li>
<Link to="/color-picker">Color Picker</Link>
</li>
</ul>
</Router>
</main>,
document.getElementById('root')
);
This is the output:
The links need to be above the outputted component, so:
But I don't know how to figure it out, and there are no helpful answers on stack overflow.
I tried:
ReactDOM.render(
document.getElementById('root'),
<main className="content-area">
<Router>
<Route path="/counter" component={Counter} />
<Route path="/color-picker" component={ColorPicker} />
<ul>
<li>
<Link to="/">Main Page</Link>
</li>
<li>
<Link to="/counter">Counter</Link>
</li>
<li>
<Link to="/color-picker">Color Picker</Link>
</li>
</ul>
</Router>
</main>
);
But everything goes blank with no errors.
I feel like this answer - Using React-Router with a layout page or multiple components per page - could be what I'm looking for but to be honest I don't understand it.
How do I change the order of react router links?
As #azium said in the comments, you need to reorder your html code to put the links before the routes, not reorder the arguments of the ReactDOM.render method.
ReactDOM.render(
<main className="content-area">
<Router>
<ul>
<li>
<Link to="/">Main Page</Link>
</li>
<li>
<Link to="/counter">Counter</Link>
</li>
<li>
<Link to="/color-picker">Color Picker</Link>
</li>
</ul>
<Route path="/counter" component={Counter} />
<Route path="/color-picker" component={ColorPicker} />
</Router>
</main>,
document.getElementById('root')
);