I am trying to navigate and show different components on different route .
so my index.js looks like this
ReactDOM.render(<Routes />, document.getElementById('root'));
then render function of my Routes component is like
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/admin/add-product" component={AdminAddProduct}/>
</Switch>
</BrowserRouter>
);
}
so i have navbar component where on clicking i have defined the actions
render() {
return (
<Router>
<MDBNavbar color="default-color" dark expand="md">
<MDBNavbarToggler onClick={this.toggleCollapse} />
<MDBCollapse id="navbarCollapse3" isOpen={this.state.isOpen} navbar>
<MDBNavbarNav left>
<MDBNavItem>
<MDBNavLink to="/">Shop</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink to="/admin/add-product">Admin product</MDBNavLink>
</MDBNavItem>
</MDBNavbarNav>
</MDBCollapse>
</MDBNavbar>
</Router>
);
}
}
so initially when i am in ' / ' i am seeing my Homepage component as i have defined in routes.js file but then when i click on Admin product the routes go to /admin/add-product but then the component is not rendered on screen
If i refresh my page staying on that route then only i am able to see the contents of AdminAddProduct page.
Without seeing the entire structure of your app, I don't know if this is good advice. I am assuming you also have an app.js file.
You will need app.js in your index.js file and it should be wrapped the Router.
Your index.js file should look something like this:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root')
);
Notice that BrowserRouter is in index.js, not in the Routes component, in this example.
Also, make sure that your Routes component is imported into App.js or write this logic directly in App.js.
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/admin/add-product" component={AdminAddProduct}/>
</Switch>
This might be conflict problem depending on you react-router-dom and mdbootstrap version since the react-router-dom version 5.0.0v had a conflict with MDBNavLink component but the issue has been resolved for react-router-dom version 5.0.1v so try upgrading the react-router-dom version to the latest
npm i react-router-dom#latest
Related
I'm using react-router-dom 6.8.1 and react 18.2.0 and trying to set up browser router using the createBrowserRouter() and createRoutesFromElements() functions. I'm then rendering my browser router using the <RouterProvider> component, and the front page of my website displays fine (the App component does). For some reason, any react-router-dom <Link> components I place in my components appear on the front page, but when I click them, only the URL changes, and it does not update the UI. What's weird is that if I use an <Outlet>, the UI from the child routes will display when I click any links, but that's not what I want. I need to navigate to a separate page.
Here's where I'm creating the browser router:
import * as ReactDOM from 'react-dom/client';
import {
createBrowserRouter,
createRoutesFromElements,
Route,
RouterProvider,
} from 'react-router-dom';
import App from './app/app';
import ParticipantProfile from './app/profiles/participantProfile';
const browserRouter = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<App />}>
<Route path="profile" element={<ParticipantProfile />} />
</Route>
)
);
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(<RouterProvider router={browserRouter} />);
Here's where I create my <Link>:
import { Link } from 'react-router-dom';
import { createTheme } from '#mui/material/styles';
const theme = createTheme();
function App() {
return <Link to="profile">Profile</Link>;
}
export default App;
I'm tried rendering the <BrowserRouter> component itself instead of using createRoutesFromElements, but same results. Changing the path from profile to /profile also seems to do nothing.
If you want each route to map to a different component (without layout nesting), there is no need to wrap them all under a single <Route> element.
<>
<Route path="/" element={<App />} />
<Route path="/profile" element={<ParticipantProfile />} />
</>
Alternatively, only specify the element on the child route.
<Route path="/">
<Route index element={<App />} />
<Route path="profile" element={<ParticipantProfile />} />
</Route>
I am using React Router to navigate to different pages, each one being a different React Component. If I go to the home page first (e.g. /) then click a Link to take me to a different component (e.g. /new-guide), it renders fine. However, when I push the project to production using AWS or Netlify, accessing any component fails without first going to the home component.
Here's what it looks like in action. If you visit https://www.kelv.me/ then click the 'Gap Year' guide, the gap year component renders correctly. However, if you close the tab and try to visit https://www.kelv.me/gap-year directly, a 'Page not found' error occurs.
Here's my App.js:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import GapYear from './components/GapYear';
function App() {
return (
<Fragment>
<Router>
<Fragment>
<div id='content'>
<Switch>
<Route exact path='/' component={Landing} />
<Route exact path='/gap-year' component={GapYear} />
</Switch>
</div>
</Fragment>
</Router>
</Fragment>
);
}
export default App;
And here's my index.js:
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter as Router } from 'react-router-dom';
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root')
);
I am learning React Routing and I am watching this tutorial:
https://www.youtube.com/watch?v=1iAG6h9ff5s
Its 2016 tutorial so I suppose something changed because 'react-router' not working anymore and I am supposed to use 'react-router-dom'.
I found that I must uninstall 'history' and 'react-router' and use 'react-router-dom' instead, but It not working as expected when I change it.
How to edit this to make it working with 'react-router-dom'?
import React from "react";
import ReactDOM from "react-dom";
import {Router, Route, IndexRoute, hashHistory} from "react-router";
import Layout from "./pages/Layout";
import Archives from "./pages/Archives";
import Featured from "./pages/Featured";
import Settings from "./pages/Settings";
const app = document.getElementById('app');
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
<IndexRoute component={Featured}></IndexRoute>
<Route path="archives" component={Archives}></Route>
<Route path="settings" component={Settings}></Route>
</Route>
</Router>,
app);
My edit:
import React from "react";
import ReactDOM from "react-dom";
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import Layout from "./pages/Layout";
import Archives from "./pages/Archives";
import Featured from "./pages/Featured";
import Settings from "./pages/Settings";
const app = document.getElementById('app');
ReactDOM.render(
<Router>
<Route path="/" component={Layout}>
<Route path="/featured" component={Featured}/>
<Route path="/archives" component={Archives}/>
<Route path="/settings" component={Settings}/>
</Route>
</Router>,
app);
Also pushState not working...
Layout.js
import React from "react";
import {Link} from "react-router-dom";
export default class Layout extends React.Component {
navigate() {
this.props.history.pushState(null, "/");
}
render() {
return (
<div>
{this.props.children}
<h1>Welcome</h1>
<button onClick={this.navigate.bind(this)}>Featured</button>
</div>
);
}
}
When I click to Link url change, but content is not loaded... Also when I access url I get "Cannot GET" error
After watching the video, you probably want something like this. At first this would not be so easy to understand but after seeing a few of them you digest it. First you render your Layout with one Route. Then in this top route, you use other Routes to setup your components.
We usually use exact props for a top root like /. If you don't setup your app like that, for example all your routes is in your top Router config, then to use a route something like /featured we must have exact prop. If we don't use it Router always hit / path and we always see the top level component.
But, in your situation, you want other components to be routed in your top level component. So, we drop exact prop here.
Also you can use push to change history.
Update
After think about the navigation button named "Featured", I think you want the Featured component rendered as default one here. When hit the button again you will come back to Featured one. I've changed the code according to that. In this version, we add a / route in the Layout and point it to Featured. So, when we come here it is rendered. But, we use exact prop here since we also want routes like "/featured", "/archives" and "/settings".
export default class Layout extends React.Component {
navigate = () => this.props.history.push("/");
render() {
return (
<div>
<h1>Welcome</h1>
<Link to="/featured">Featured</Link>
<Link to="/archives">Archives</Link>
<Link to="/settings">Settings</Link>
<br />
<button onClick={this.navigate}>Featured</button>
<Route exact path="/" component={Featured} />
<Route path="/featured" component={Featured} />
<Route path="/archives" component={Archives} />
<Route path="/settings" component={Settings} />
<div>
Some other info.
</div>
</div>
);
}
}
const app = document.getElementById('root');
ReactDOM.render(
<Router>
<Switch>
<Route path="/" component={Layout} />
</Switch>
</Router>,
app);
I have a setup in electron with react router. When I load the app into my browser, and don't go via electron, everything works fine, and the router is good.
When I use it in electron however, my software is not at the root route initially. I can navigate to the root route with the links I created, and that works fine. But it's not there initially, I get a 404. But I don't get any errors as such.
So when i start it, it looks like this:
But the Links all work, so I can click for example on Home at am redirected to the Home route:
My switch looks like this:
<Switch>
<Route exact path='/' component={Home}/>
<Route component={NotFound}/>
</Switch>
And that component sits in another component:
import React from 'react';
import Header from './Header.jsx'
import Main from './Main.jsx'
export default class App extends React.Component {
render() {
return (
<div style={{textAlign: 'center'}}>
<Header />
<Main />
</div>);
}
}
which sits in this component:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.jsx';
import {BrowserRouter} from 'react-router-dom'
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root'));
and here is also the Main.js which holds the Routes:
const Main = () => (
<main>
<Switch>
<Route exact path='/' component={Home}/>
<Route component={NotFound}/>
</Switch>
</main>
)
So as far as I am concerned, everything should be working fine, and, as I said, it does in the browser. But electron does not seem to start my react router at /. Why could this be?
I have these two components that are completely independent of each other. I want to render App when I enter / and render About when I go to /#/about
I got this piece of code (but I tested quite a few others):
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, browserHistory } from 'react-router'
import App from './App';
import About from './About';
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={App} >
<Route path="/about" component={About} />
</Route>
</Router>
, document.getElementById('root')
);
I also tried something like
<Route path="/about" component={About} />
<Route path="/" component={App} />
And changed /about to /#/about, about
But it always render the "fallback" /, it always goes to this route, no matter what.
How can I make this app navigate properly to / and /about and render the App and the About components?
#edit
Assuming that my About component is broken, I removed the first Route and kept only the /about (kept only the /about Route) :
<Route path="/about" component={App} />
(I tried keeping About as well in a previous test) and also changed the /about to about and /#/about.
And I get this error on console:
"VM3651 bundle.js:30801 Warning: [react-router] Location "/#/about" did not match any routes"
#edit 2
I made a change, following the example #Dominic posted. I had to make some modifications to make sure both components would render. I added the {this.props.children} to all Components to understand what would happen.
//imports
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={About} >
<IndexRoute component={App} />
<Route path="/about" component={Other} />
</Route>
</Router>
,document.getElementById('root'));
The route http://localhost:3000/#/about is rendering:
> About > App
So it is rendering the IndexRoute, it is not getting caught by the /about.
And this is now exactly what I need, because I didn't want a root component, I wanted 2 routes to 2 different and isolated components. I need something like two sibling routes.
#edit
The About.js
import React, { Component } from 'react';
class About extends Component {
render() {
return (
<div>
About page
{this.props.children}
</div>
);
}
}
export default About;
Solution:
Since I'm using a HASH (#) in the URL, I should use hashHistory from React Router in the <Router history={hashHistory}>
You're confusing how routes work - About is a child of the App route, so in order to render About, it has to render App.
In other words your App component is the "shell" and all components under it render INSIDE it (via props.children).
You should add another route to render /.
import { ..., IndexRoute } from 'react-router'
<Route path="/" component={App} >
<IndexRoute component={Home} />
<Route path="about" component={About} />
</Route>
Your App does not contain route specific content, it would be something more like this:
<div id="app">
<nav>app navigation</nav>
<main class="route-content">{props.children}</main>
</div>
Docs: https://github.com/ReactTraining/react-router/blob/master/docs/guides/RouteConfiguration.md#adding-an-index
Those routes look correct to me. Are you getting any errors in the console? Maybe your About component is undefined and thus not rendering. Can you post your About component?