Setting up react-router and I'm getting an error Uncaught Error: <Link>s rendered outside of a router context cannot navigate.. I've read up everything I could find on github and here but I didn't find a solution that worked.
Here are the files in question.
Main.js
import React from 'react';
import { BrowserRouter, Route, BrowserHistory } from 'react-router-dom';
import Header from './components/Header/Header';
import Home from './components/Home/Home';
import About from './components/About/About';
import Apply from './components/Apply/Apply';
import Raiding from './components/Raiding/Raiding';
import Resources from './components/Resources/Resources';
import Register from './components/Register/Register';
import Footer from './components/Footer/Footer';
const Main = () => {
return (
<div>
<Header />
<BrowserRouter history={BrowserHistory}>
<main>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/apply' component={Apply} />
<Route path='/raiding' component={Raiding} />
<Route path='/resources' component={Resources} />
<Route path='/register' component={Register} />
</main>
</BrowserRouter>
<Footer />
</div>
)
}
export default Main;
Header.js
import React, { Component } from 'react';
import {BrowserRouter, Link } from 'react-router';
const Header = () => {
return (
<header id="site-header">
<div className="container">
<img src="http://placehold.it/200x100" alt=""/>
<nav id="site-nav">
<Link className="site-nav-link" to="/about">About</Link>
<Link className="site-nav-link" to="/apply">Apply</Link>
<Link className="site-nav-link" to="/raiding">Raiding</Link>
<Link className="site-nav-link" to="/resources">Resources</Link>
<Link className="site-nav-link" to="/register">Register</Link>
</nav>
</div>
</header>
)
}
export default Header;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Main from './app/Main';
import 'normalize.css';
import './index.scss';
ReactDOM.render(<Main />, document.querySelector('#root'));
What I am assuming is that the issue lies in the fact that my Header component (which contains Links) is out of context of the Main component (which contains the routing) but I haven't figured out a solution for it.
<Link> components depend on the context.router being present. context.router is set by the <BrowserRouter>. You should be rendering your <Header> component inside of the <BrowserRouter> and it will work as expected.
<BrowserRouter>
<div>
<Header />
<main>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/apply' component={Apply} />
<Route path='/raiding' component={Raiding} />
<Route path='/resources' component={Resources} />
<Route path='/register' component={Register} />
</main>
<Footer />
</div>
</BrowserRouter>
Side note, but BrowserHistory is not a thing in v4. The <BrowserRouter> is creating a history instance for you.
Related
I am trying to use the router in react but I get nothing when changing the path, you can check the code here Link ..............................
import React from "react";
import Layout from "./Layout";
import Home from "./Home";
import About from "./About";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
function App() {
return (
<Layout>
<Router>
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/About" element={<About />} />
</Routes>
</Router>
</Layout>
);
}
export default App;
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
function Layout({ children }) {
return (
<div>
<Router>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</Router>
<div>{children}</div>
</div>
);
}
export default Layout;
Place the <div>{children}</div> inside <Router>, then in app.js remove Router. Because that has already been declared in <Layout>
Layout.js
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
function Layout({ children }) {
return (
<div>
<Router>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<div>{children}</div>
</Router>
</div>
);
}
export default Layout;
App.js
import React from "react";
import Layout from "./Layout";
import Home from "./Home";
import About from "./About";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
function App() {
return (
<Layout>
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/About" element={<About />} />
</Routes>
</Layout>
);
}
export default App;
Your current code will output the following:
<div>
<Router>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</Router>
{/* Children (App.js) */}
<Router>
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/About" element={<About />} />
</Routes>
</Router>
{/* Children (App.js) */}
</div>
You don't need two instances of <Router>.
This how it should be:
<Router>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
{/* Children (App.js) */}
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/About" element={<About />} />
</Routes>
{/* Children (App.js) */}
</Router>
you need to remove Router from your route wrap
import React from "react"; import Layout from "./Layout"; import Home from "./Home"; import About from "./About"; import { BrowserRouter as Routes, Route } from "react-router-dom";
function App() { return (
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/About" element={<About />} />
</Routes>
); }
export default App;
The Problem is, that you have two different Routers in your Application.
You need to move the Layout Component inside your Routercomponent in App.js
And then delete the second router inside of Layout.
More info here:
Error: useHref() may be used only in the context of a <Router> component. It works when I directly put the url as localhost:3000/experiences
**App.js**
import './App.css';
import Header from "./Header.js";
import Home from "./Home.js";
import Checkout from "./Checkout.js";
import { BrowserRouter as Router, Route, Routes} from "react-router-dom";
function App() {
return (
<div className="App">
<Router>
<Header />
<Routes>
<Route path="/checkout" element={Header}/>
<Route exact path="/checkout" element={<Checkout />}/>
<Route exact path="/" element={<Home />}/>
<Route exact path="/" element={<Header />}/>
</Routes>
</Router>
</div>
);
}
export default App;
checkout.js
import React from 'react';
import "./Checkout.css";
import CheckoutProduct from "./CheckoutProduct.js";
import Subtotal from "./Subtotal.js";
function Checkout() {
return (
<div className="checkout">
<div className="checkout__left">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSlDIcv46GCe2DRvW-CmLDn5LHyORLkJo8isA&usqp=CAU" alt="" className="checkout__add" />
<div>
<h2 className="checkout__title">
your Shopping Basket
</h2>
<CheckoutProduct />
</div>
</div>
<div className="checkout__right">
<Subtotal />
</div>
</div>
)
}
export default Checkout
I am expecting after routing to checkout component it should display all the content written inside it. but I am only seeing blank screen.(I am following the same code structure from the Udemy video)
I'm new to learning React so I'm wondering if anyone can help me. I'm currently building a portfolio through React and I'm working on the Nav for this. I'm not getting any errors in the Console and when I click on each Link, it displays the Link I've clicked on in the URL but it won't show me any of my Content from each Link. Can anyone please help explain where I am going wrong?
App Code
import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom';
import Projects from './Projects.js';
import Contact from './Contact.js';
import About from './About.js';
import Skills from './Skills.js';
import Home from './App.js';
import './App.css';
function App() {
return (
<BrowserRouter>
<div className="App">
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<About />}></Route>
<Route path="/contact" element={<Contact />}></Route>
<Route path="/projects" element={<Projects />}></Route>
<Route path="/skills" element={<Skills />}></Route>
<div className="navigation">
<div className="navigation-sub">
<Link to="/" className="item">Home</Link>
<Link to="/about" className="item">About</Link>
<Link to="/contact" className="item">Contact</Link>
<Link to="/projects" className="item">Projects</Link>
<Link to="/skills" className="item">Skills</Link>
</div>
</div>
</div>
</BrowserRouter>
);
}
export default App;
index Code
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();
About Code
import React from "react";
function About(props) {
return (
<div>
<h1>About Me</h1>
</div>
)
}
export default About;
Thanks :)
You are already rendering a BrowserRouter around App, so remove the extraneous BrowserRouter from App. The Route components are also missing being wrapped in a Routes component that handles path matching. It's a required component. You should have some console errors warning of invariant violations for the rendering of a router within another router and the routes not being wrapped directly by a Routes component.
import { Routes, Route } from 'react-router-dom';
function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/projects" element={<Projects />} />
<Route path="/skills" element={<Skills />} />
</Routes>
<div className="navigation">
<div className="navigation-sub">
<Link to="/" className="item">Home</Link>
<Link to="/about" className="item">About</Link>
<Link to="/contact" className="item">Contact</Link>
<Link to="/projects" className="item">Projects</Link>
<Link to="/skills" className="item">Skills</Link>
</div>
</div>
</div>
);
}
I'm using react-router-dom but my routes are somehow not working. the routes are not redirected to the component. I don't have any error in the console, and I did npm install react-router-dom. I can't see what I've done wrong. You can find my code below. Any help will be welcome.
This is my App.js page
import React from 'react';
import './App.css';
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
import LoginButton from './components/LoginButton';
import Register from './components/Register';
import Login from './components/Login';
function App() {
return (
<Router>
<div>
<div className="cover d-flex justify-content-center align-items-center">
<div className="text-white">
<h1 className="text-center fw-bold">GREEN</h1>
<p className="lead fw-bold">CARBON FOOTPRINT CALCULATOR</p>
<LoginButton />
</div>
</div>
<Switch>
<Route path="/register">
<Register />
</Route>
<Route path="/login">
<Login />
</Route>
<Route path="/">
<App />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
This is the component page
import React, { Component } from 'react';
import './LoginButton.css'
import { Link } from "react-router-dom";
export default class LoginButton extends Component {
render() {
return (
<div>
<div className="login-container">
<Link to="/register"><button className="signup-button">SIGN UP</button></Link>
<Link to='/login'><button className="login-button">LOG IN</button></Link>
</div>
</div>
)
}
}
assuming you know the difference between import {component} from component and import component from component. In my example below I'm using the import {component} from component;.
The React Router works something like this:
<Router>
<div>
<div className="cover d-flex justify-content-center align-items-center">
<div className="text-white">
<h1 className="text-center fw-bold">GREEN</h1>
<p className="lead fw-bold">CARBON FOOTPRINT CALCULATOR</p>
<LoginButton />
</div>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/register' component={Register} exact />
<Route path='/login' component={Login} exact />
</Switch>
Edit:
You're using <Route path="/"> <App /> </Route> which is the entry point itself in App.js. You've a syntax error in your App.js file.
Not sure but I guess that putting <Link>, <button> together can make "event bubbling" problem.
To make sure this problem, How about to change <button> to just plain dom like <div>
Please tell me what's wrong in this when I am clicking on nav link the url is changing but the content is not changing
I am trying all the ways but can't figure out the problem, please have a look at this
App.js
import React, { Component } from 'react';
import './App.css';
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
import Home from './components/Home';
import About from './components/About';
import Nav from './components/Nav';
import Contact from './components/Contact';
class App extends Component {
render(){
return (
<React.Fragment>
<div id="page-wrapper">
<Router>
<Nav />
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" exact component={About} />
<Route path="/contact" exact component={Contact} />
<Route ><Default /></Route>
</Switch>
<Footer />
</Router>
</div>
</React.Fragment>
);
}
}
export default App;
My link file i.e nav bar
<Link to="/">
<li className="nav-item">HOME</li>
</Link>
<Link to="/about">
<li className="nav-item">About</li>
</Link>
Thanks in advance
Moving your BrowserRouter to index.js seems to work in my end.
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
Then remove <Router> from your code.