In my index.js file:
import React from 'react';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom';
import App from './App';
import Contact from './Contact';
import ReactDOM from 'react-dom';
//import RouterMapping from './RouterMapping';
const RouterMapping = () => (
<Router>
<Route exact path='/' component={App} />
<Route path='/contact' component={Contact} />
</Router>
);
ReactDOM.render(
<RouterMapping />,
document.getElementById('root')
);
When rendering the page /, it displays nothing (should go to App component per my understanding. The App component itself is running OK if I replace:
ReactDOM.render(
<RouterMapping />,
document.getElementById('root')
);
to
ReactDOM.render(
<App />,
document.getElementById('root')
);
Did I do something fundamentally wrong? Newbie to React...
Update on Mar 16
I think I figured out how to make the router work.
I have refactored my RouterMapping to RoutingConfig as below:
import React from 'react';
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
import Home from './Home';
import Contact from './Contact';
const RoutingConfig = () => (
<Router>
<div>
<Route exact path="/" component={Home}/>
<Route path="/contact" component={Contact}/>
</div>
</Router>
);
export default RoutingConfig;
Nothing peculiar.
Now, instead of rendering RoutingConfig in my index.js, I still render the App component in my index.js:
ReactDOM.render(
<App />,
document.getElementById('root')
);
The routing mapping is done now in App.js:
class App extends Component {
render() {
return (
<RoutingConfig />
);
}
}
Now it works. Please see attached screenshot:
My explanation
I think the key here is to demote the RoutingConfig to App.js. From index.js render App.js, App.js will act as the entry point to my whole app and determine which component (Home, Contact) to load based on routing.
Above for your information and hope it is helpful.
Related
Im routing a page to the root, but its showing up as a blank page, no matter what js file I use. Not sure whats wrong, havent used react since last year but looks like they've updated react-router-dom so it doesnt use Switch anymore. Anyone know the correct syntax so the page shows up? Here are the files:
WebRoutes.js
import React from "react";
import { Routes, Route } from 'react-router-dom';
import { useNavigate } from "react-router-dom";
// Webpages
import App from './App';
import Welcome from './welcome';
import SignUp from './Signup'
export default function WebRoutes() {
return (
<Routes>
<Route path='/'>
<Welcome />
</Route>
</Routes>
);
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import WebRoutes from './WebRoutes';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<WebRoutes />
</React.StrictMode>,
document.getElementById('root')
);
In react-router-dom#6 the Route components don't render routed content as children, they use the element prop. Other Route components are the only valid children of a Route in the case of building nested routes.
export default function WebRoutes() {
return (
<Routes>
<Route path='/' element={<Welcome />} />
</Routes>
);
}
Ensure that you have rendered a router around your app.
import { BrowserRouter as Router } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<WebRoutes />
</Router>
</React.StrictMode>,
document.getElementById('root')
);
I have a navbar that is rendered in every route while the route changes on click.
./components/navbar.jsx
import React, { Component } from 'react';
import '../App.css';
import { Link } from 'react-router-dom';
class Navbar extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div id = 'navbar'>
<div className='name-head'>
My Name
</div>
<div id = 'nav-links-container'>
<Link to='/experiences'>
<div className = 'nav-links'>
Experiences
</div>
</Link>
<div className = 'nav-links'>
Projects
</div>
<div className = 'nav-links'>
Skills
</div>
<div className = 'nav-links'>
Resume
</div>
</div>
</div>
);
}
}
export default Navbar;
./components/experiences.jsx
import React, { Component } from 'react';
class Experiences extends Component {
render() {
return (
<div>
<h1>hi</h1>
</div>
);
}
}
export default Experiences;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Navbar from './components/Navbar';
import Home from './components/Home';
import Experiences from './components/experience';
import {
BrowserRouter as Router,
Routes,
Route
} from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Navbar />
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
The error doesn't come when I remove the <Link> from the experiences tag in navbar.
There is a similar question posted here: Error: useHref() may be used only in the context of a <Router> component
but doesn't help.
I'm using react router v6
Issue
You are rendering the navbar outside the routing context. The Router isn't aware of what routes the links are attempting to link to that it is managing. The reason routing works when directly navigating to "/experiences" is because the Router is aware of the URL when the app mounts.
<Navbar /> // <-- outside router!!
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
Solution
Move it inside the routing context so the Router is aware and can manage routing correctly.
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
react-router-dom#6.4 Data APIs
If you are using the new Data routers you can hit this issue if you attempt to render a header/navbar outside the RouterProvider component. For this you can create a layout route that is part of the routing configuration passed to createBrowserRouter (and other variants).
Example:
const AppLayout = () => (
<>
<Navbar />
<Outlet />
</>
);
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<AppLayout />}>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Route>
)
);
...
<RouterProvider router={router} />
in React Route v6 you can solve this giving the route context to your entire App with <BrowserRouter>
This is an complete example of index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { App } from './components/App/App.jsx';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter> //that is the key
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
If you are still having problem with this one, it is because react-router-dom relies on React context to work when you try to unit-test it. This makes <Link /> or <Route /> obsolete.
Try reading the react-router-dom documentation.
Instead of using
render(<Example />)
that have either or inside it, you can try
render(<MemoryRouter>
<Example />
</MemoryRouter>)
Hope this solves your problem
In react-router-dom:6.x and react:18.x, we should use the Router in the following way to resolve the issue:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { App } from './App.js';
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Router> // Router
<App /> // Application
</Router>
</React.StrictMode>
);
Links are inside Navbar &
Navbar is outside of Router
=> links are outside of Router => Router will not manage Links
Solution
Move the Navbar into Router section. Example:
<Router>
<Navbar /> // <===========
<Routes>
<Route />
<Route />
</Routes>
</Router>
Wrap navbar with BrowserRouter
import { BrowserRouter, Routes, Route } from "react-router-dom";
<BrowserRouter>
<AppNavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/wall" element={<WallPost />} />
</Routes>
</BrowserRouter>
Install in your project React Router v6.
npm install react-router-dom#6
Then use BrowserRouter in your index.js file, below like this:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
React Router v6 this problem common one, you can simply replace "index.js" code. you will got solution-
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
This error happens because Link component needs to reach out to react-router context object. Your Navbar component is using Link component but Navbar is not wrapped by router context.
A similar error happens in a testing environment. If you have a component that uses Link component and if you render this component in a testing environment, you will get the same error because Link component needs to access a router context. In the case of test environment:
import { render } from "#testing-library/react";
// this will throw same error
test("testing", () => {
render(<ComponentRendersLink/>);
});
Solution in this case to wrap it with a router
// there are more router options
import { MemoryRouter } from "react-router-dom";
render(
<MemoryRouter>
<ComponentRendersLink />
</MemoryRouter>
);
This is very much an edge case, but in my case it turned out a lib I develop had react-router-dom: 6.0.2 installed and project that uses it v6.3.0
Your links just needs to be within a BrowserRouter component since you use v6
After importing
<BrowserRouter>
<Link to='page'>
</BrowserRouter>
I have a navbar that is rendered in every route while the route changes on click.
./components/navbar.jsx
import React, { Component } from 'react';
import '../App.css';
import { Link } from 'react-router-dom';
class Navbar extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div id = 'navbar'>
<div className='name-head'>
My Name
</div>
<div id = 'nav-links-container'>
<Link to='/experiences'>
<div className = 'nav-links'>
Experiences
</div>
</Link>
<div className = 'nav-links'>
Projects
</div>
<div className = 'nav-links'>
Skills
</div>
<div className = 'nav-links'>
Resume
</div>
</div>
</div>
);
}
}
export default Navbar;
./components/experiences.jsx
import React, { Component } from 'react';
class Experiences extends Component {
render() {
return (
<div>
<h1>hi</h1>
</div>
);
}
}
export default Experiences;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Navbar from './components/Navbar';
import Home from './components/Home';
import Experiences from './components/experience';
import {
BrowserRouter as Router,
Routes,
Route
} from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Navbar />
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
The error doesn't come when I remove the <Link> from the experiences tag in navbar.
There is a similar question posted here: Error: useHref() may be used only in the context of a <Router> component
but doesn't help.
I'm using react router v6
Issue
You are rendering the navbar outside the routing context. The Router isn't aware of what routes the links are attempting to link to that it is managing. The reason routing works when directly navigating to "/experiences" is because the Router is aware of the URL when the app mounts.
<Navbar /> // <-- outside router!!
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
Solution
Move it inside the routing context so the Router is aware and can manage routing correctly.
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Routes>
</Router>
react-router-dom#6.4 Data APIs
If you are using the new Data routers you can hit this issue if you attempt to render a header/navbar outside the RouterProvider component. For this you can create a layout route that is part of the routing configuration passed to createBrowserRouter (and other variants).
Example:
const AppLayout = () => (
<>
<Navbar />
<Outlet />
</>
);
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<AppLayout />}>
<Route path="/" element={<Home />} />
<Route path="/experiences" element={<Experiences />} />
</Route>
)
);
...
<RouterProvider router={router} />
in React Route v6 you can solve this giving the route context to your entire App with <BrowserRouter>
This is an complete example of index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { App } from './components/App/App.jsx';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter> //that is the key
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
If you are still having problem with this one, it is because react-router-dom relies on React context to work when you try to unit-test it. This makes <Link /> or <Route /> obsolete.
Try reading the react-router-dom documentation.
Instead of using
render(<Example />)
that have either or inside it, you can try
render(<MemoryRouter>
<Example />
</MemoryRouter>)
Hope this solves your problem
In react-router-dom:6.x and react:18.x, we should use the Router in the following way to resolve the issue:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { App } from './App.js';
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Router> // Router
<App /> // Application
</Router>
</React.StrictMode>
);
Links are inside Navbar &
Navbar is outside of Router
=> links are outside of Router => Router will not manage Links
Solution
Move the Navbar into Router section. Example:
<Router>
<Navbar /> // <===========
<Routes>
<Route />
<Route />
</Routes>
</Router>
Wrap navbar with BrowserRouter
import { BrowserRouter, Routes, Route } from "react-router-dom";
<BrowserRouter>
<AppNavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/wall" element={<WallPost />} />
</Routes>
</BrowserRouter>
Install in your project React Router v6.
npm install react-router-dom#6
Then use BrowserRouter in your index.js file, below like this:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
React Router v6 this problem common one, you can simply replace "index.js" code. you will got solution-
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
This error happens because Link component needs to reach out to react-router context object. Your Navbar component is using Link component but Navbar is not wrapped by router context.
A similar error happens in a testing environment. If you have a component that uses Link component and if you render this component in a testing environment, you will get the same error because Link component needs to access a router context. In the case of test environment:
import { render } from "#testing-library/react";
// this will throw same error
test("testing", () => {
render(<ComponentRendersLink/>);
});
Solution in this case to wrap it with a router
// there are more router options
import { MemoryRouter } from "react-router-dom";
render(
<MemoryRouter>
<ComponentRendersLink />
</MemoryRouter>
);
This is very much an edge case, but in my case it turned out a lib I develop had react-router-dom: 6.0.2 installed and project that uses it v6.3.0
Your links just needs to be within a BrowserRouter component since you use v6
After importing
<BrowserRouter>
<Link to='page'>
</BrowserRouter>
I am relatively new to React and can't for the life of me figure out why this isn't working!
This code is not loading the App component inside router, but it does when returned independently. Example below
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { Router, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Route path="/">
<App />
</Route>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
Nothing loads on the screen with this. However when I remove the router I see the App component load:
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { Router, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<App />,
// <Router>
// <Route path="/">
// <App />
// </Route>
// </Router>,
document.body.appendChild(document.createElement("div"))
);
});
Finally, this is my App component (dont think you need this though)
import React from "react";
const App = () => {
return <div>app has loaded</div>;
};
export default App;
This is built on a Ruby on Rails app, if that matters
if you'are using react-router-dom v5:
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Switch>
<Route path="/">
<App />
</Route>
</Switch>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
if you're using react-router-dom v6
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
Instead of
import { Router, Route } from "react-router-dom";
try
import { BrowserRouter, Route } from "react-router-dom";
What versions of react and react-router-dom are you using? This works for me in a fresh npx create-react-app:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter, Routes, Route } from "react-router-dom"; // BrowserRouter as Router
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<div>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
</Routes>
</BrowserRouter>
</div>,
document.body.appendChild(document.createElement("div"))
);
});
Fixed:
import React from "react";
import ReactDOM from "react-dom";
import App from "../components/App";
import { Router, Route, Switch } from "react-router-dom";
document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/">
<App />
</Route>
</Switch>
</Router>,
document.body.appendChild(document.createElement("div"))
);
});
If you have followed all the steps, then the answer may just be that you installed the NPM package in the wrong place.
Make sure it is in your project folders JSON file.
Considering you're new to React it is pretty easy to install packages in the wrong place.
I may have done silly mistake this time but I am but getting it what. I started with react router v4 but my routing is not happening. I try to hit url manually as well as by button click no result. here's my route config. and FYI I am using LinkContaier to redirection
import ReactDOM from 'react-dom';
import React from 'react';
import { Provider } from 'react-redux';
import configureStore from './stores/configureStores';
import {BrowserRouter,Route,Switch} from 'react-router-dom'
import HeaderContainer from "./containers/HeaderContainer"
import ProgramProfileContainer from "./containers/ProgramProfileContainer"
const store = configureStore();
ReactDOM.render(
<Provider store={store}>
<BrowserRouter >
<Switch>
<HeaderContainer/>
{/* <Route exact path="/" component={HeaderContainer}/> */}
<Route path="program-profile/:program_id" component={ProgramProfileContainer}/>
</Switch>
</BrowserRouter>
</Provider>, document.getElementById('root')
);
this is my container
import React from "react"
import { connect } from 'react-redux';
export default class ProgramProfileContainer extends React.Component{
render(){
console.log("program profile")
return(
<h1> this is profile </h1>
)
}
}
i hit the url like program-profile/3 but rendered nothing no error in console also
Don't use switch inside browser router :
ReactDOM.render(
<Provider store={store}>
<BrowserRouter >
<div>
<Route exact path="/" component={HeaderContainer}/>
<Route path="/program-profile/:program_id" component={ProgramProfileContainer}/>
</div>
</BrowserRouter>
</Provider>, document.getElementById('root')
);
Your answer seems to be ok. But this is how I do it normally.
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import promise from 'redux-promise';
import reducers from './reducers';
import ProgramProfileContainer from "./containers/ProgramProfileContainer"
const store = configureStore();
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<div>
<Switch>
<Route path="program-profile/:program_id" component={ProgramProfileContainer} />
<Route path="/" component={IndexPage} />
</Switch>
</div>
</BrowserRouter>
</Provider>
, document.querySelector('.container'));
When you use Link it should be like this.
<Link to={`/posts/${post.id}`}>
{post.title}
</Link>
If you have any error messages in console, please post them so that we can help you further. Hope this helps. Happy coding.