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
Related
I currently have my app as follows with my routes wrapped inside of BrowserRouter and I am receiving
Uncaught Error: You cannot render a <Router> inside another <Router>
Below is my codesandbox
I did a
ctl + F + Shift
and only have 1 router in my app. Does anyone see a syntax error or have a suggestion?
Codesandbox
Here is my App component:
import { BrowserRouter, Routes, Route, Router, Link } from "react-router-dom";
import Header from "./components/Header/Header";
import Features from "./components/body/Features/FeaturesGrid/FeaturesGrid";
import Artists from "./components/body/Artists/Artists";
import Fans from "./components/body/Fans/Fans";
import Groups from "./components/body/Groups/Groups";
import Footer from "./components/body/Footer/Footer";
import PPV from "./components/body/PPV/PPV";
function App() {
return (
<BrowserRouter>
<nav>
<Header />
</nav>
<Routes>
<Route path="/" element={<App />} />
<Route path="/features" element={<Features />} />
<Route path="/artists" element={<Artists />} />
<Route path="/fans" element={<Fans />} />
<Route path="/groups" element={<Groups />} />
<Route path="/ppv" element={<PPV />} />
{/* <Route path="/feed" element={<Feed />} /> */}
</Routes>
</BrowserRouter>
);
}
export default App;
Here is my Header component:
import { useState } from "react";
import HeaderCSS from "../Header/Header.module.css";
import Menu from "../../svgs/bars-solid.svg";
import Close from "../../svgs/times-solid.svg";
import Logo from "../../svgs/logotrans.svg";
import { Link } from "react-router-dom";
function Header() {
const [menu, setMenu] = useState(false);
const toggleMenu = () => {
setMenu(!menu);
};
const styleMenu = {
left: menu ? 0 : "-100%",
};
return (
<header>
<div className={HeaderCSS.menu} onClick={toggleMenu}>
<img src={Menu} alt="" width="30" />
</div>
<div className="logo">
<img src={Logo} all="" width="120" height="90" />
</div>
<div className={HeaderCSS.nav_container}>
<ul style={styleMenu}>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/features">Features</Link>
</li>
<li>
<Link to="/artists">Artists</Link>
</li>
<li>
<Link to="/fans">Fans</Link>/
</li>
<li>
<Link to="/groups">Groups</Link>
</li>
<li>
<Link to="/ppv">PPV</Link>
</li>
<li>
<Link to="/feed">Feed</Link>
</li>
<li onClick={toggleMenu}>
<img src={Close} alt="" width="30" className="menu" />
</li>
</ul>
</div>
</header>
);
}
export default Header;
You are rendering App recursively
<Route path="/" element={<App />} />
You can't do that
Replace App with another component
<Route path="/" element={<div />} />
Ive been trying to fix my JS code for an E-Commerce site for a long time and nothing seems to be working, I've tried putting it in other ways and I've done quite a-lot of research in the past few weeks. If someone could help it would be very much appreciated. I cant seem to get it working so please someone help!!!
Heres my code
import React from "react";
import { Link } from "react-router-dom";
import { FaBars } from "react-icons/fa";
import { useSelector } from "react-redux"
function Header() {
const {cartItems} = useSelector(state=> state.cartReducer)
return (
<div className="header">
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<div className="container-fluid">
<Link className="navbar-brand" to="/">
Minis Services
</Link>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon">
<FaBars size={25} color="white" />
</span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav ms-auto">
<li className="nav-item">
<Link className="nav-link active" aria-current="page" to="/">
User
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/">
Software
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/">
Logout
</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/">
Cart {cartItems.length}
</Link>
</li>
</ul>
</div>
</div>
</nav>
</div>
);
}
export default Header;
Heres my app.js file
import "./App.css";
import Homepage from "./pages/Homepage";
import CartPage from "./pages/CartPage";
import Productinfo from "./pages/Productinfo";
import LoginPage from "./pages/LoginPage";
import RegisterPage from "./pages/RegisterPage";
import { Route, BrowserRouter, Routes } from "react-router-dom";
import "./stylesheets/products.css";
import "./stylesheets/layout.css";
import { Provider } from "react-redux";
function App() {
return (
<Provider>
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" exact element={<Homepage />} />
<Route path="/login" exact element={<LoginPage />} />
<Route path="/register" exact element={<RegisterPage />} />
<Route
path="/productinfo/:productid"
exact
element={<Productinfo />}
/>
<Route path="/cart" exact element={<CartPage />} />
</Routes>
</BrowserRouter>
</div>
</Provider>
);
}
export default App;
and heres my store.js file
import { createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from './rootReducer';
const composeEnhancers = composeWithDevTools({})
export const initialStore = {
cartReducer : {
cartItems : JSON.parse(localStorage.getItem(`cartItems`)) ?? []
}
}
export const store = createStore(
rootReducer,
initialStore,
composeEnhancers()
);
Heres my console error
Everything seems OK but you forgot to add store to Redux Provider
checkout this code for app.js
import "./App.css";
import Homepage from "./pages/Homepage";
import CartPage from "./pages/CartPage";
import Productinfo from "./pages/Productinfo";
import LoginPage from "./pages/LoginPage";
import RegisterPage from "./pages/RegisterPage";
import { Route, BrowserRouter, Routes } from "react-router-dom";
import "./stylesheets/products.css";
import "./stylesheets/layout.css";
import { Provider } from "react-redux";
import {store} from "/path/of/store.js/file";
function App() {
return (
<Provider store={store}>
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" exact element={<Homepage />} />
<Route path="/login" exact element={<LoginPage />} />
<Route path="/register" exact element={<RegisterPage />} />
<Route
path="/productinfo/:productid"
exact
element={<Productinfo />}
/>
<Route path="/cart" exact element={<CartPage />} />
</Routes>
</BrowserRouter>
</div>
</Provider>
);
}
export default App;
Set the path of store.js in app.js and then, I think it must work.
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.
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>
Below is the code of the react component of my project. this.props.isAuthenticatedis working when I return the component but when I print this.props.isAuthenticated inside componentDidMount I am getting false(print logout). How do I get authentication status true or false in react component?
I have added redux already and login logout working fine.
import React, { Component } from "react";
import { NavLink, Route, withRouter } from "react-router-dom";
import NewsListView from "../Container/NewsListView";
import StatsView from "../Container/StatsView";
import VotingView from "../Container/VotingView.js";
import Rightsidebar from "../Container/rightsidebar";
import Footer from "./footer";
import Loginform from "../Container/loginform";
import SignUp from "../Container/SignUp";
import { connect } from "react-redux";
import * as actions from "../Store/actions/auth";
class Header extends React.Component {
componentDidMount() {
{
this.props.isAuthenticated ? console.log("login") : console.log("logout");
}
}
render() {
return (
<div>
<nav className="navbar navbar-inverse">
<div className="container-fluid">
<div className="navbar-header">
<button
type="button"
className="navbar-toggle"
data-toggle="collapse"
data-target="#myNavbar"
>
<span className="icon-bar" />
<span className="icon-bar" />
<span className="icon-bar" />
</button>
<NavLink className="navbar-brand" to="/">
Save4thPillar
</NavLink>
</div>
<div className="collapse navbar-collapse" id="myNavbar">
<ul className="nav navbar-nav">
<li>
<NavLink to="/" className="navlink">
Home
</NavLink>
</li>
<li>
<NavLink to="/news" className="navlink">
news
</NavLink>
</li>
<li>
<NavLink to="/stats" className="navlink">
stats
</NavLink>
</li>
{this.props.isAuthenticated ? (
<li>
<NavLink
to="/logout"
onClick={this.props.logout}
className="navlink"
>
Logout
</NavLink>
</li>
) : (
<li>
<NavLink to="/login" className="navlink">
Login
</NavLink>
</li>
)}
</ul>
</div>
</div>
</nav>
<div className="container">
<div className="row">
<div className="col-md-8">
<Route exact path="/" component={VotingView} {...this.props} />
<Route exact path="/news" component={NewsListView} />
<Route exact path="/stats" component={StatsView} />
<Route exact path="/login" component={Loginform} />
<Route exact path="/signup" component={SignUp} />
</div>
<div className="col-md-4">
<Rightsidebar />
</div>
<div />
</div>
<Footer />
</div>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
logout: () => dispatch(actions.logout())
};
};
export default withRouter(
connect(
null,
mapDispatchToProps
)(Header)
);
You should implement the Header component's constructor. to use props in lifecycles
class Header extends React.Component {
componentDidMount() {
{
this.props.isAuthenticated ? console.log("login") : console.log("logout");
}
constructor(props){
super(props);
}
[...]
}