How can I make default route in React? - javascript

I am trying to make default route in my routes.js file using react-router-dom package.
This is my code:
import React from 'react';
import { Route, Switch, Router, Redirect, BrowserRouter } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import MainContainer from './containers/main';
const Routes = () => (
<BrowserRouter>
<Switch>
<Route path='/' component={MainContainer} />
<Redirect from='/' exact to='/main'/>
</Switch>
</BrowserRouter>
);
export default Routes;
But it doesn't redirect / to /main. Basically, whenever user goes to / it should redirect to /main. Also, the /main should be starting point (homepage) when I build my app. I am using create-react-app boilerplate CLI.
Thanks.

To get the effect that you want, you should, first of all, move the Redirect to the top of the Switch.
Second, you have to change the "to" property for your Route to /main. Since that is the location that you want to load your MainContainer component for.
Like so:
import React from 'react';
import { Route, Switch, Router, Redirect, BrowserRouter } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import MainContainer from './containers/main';
const Routes = () => (
<BrowserRouter>
<Switch>
<Redirect exact from='/' to='/main'/>
<Route path='/main' component={MainContainer} />
</Switch>
</BrowserRouter>
);
export default Routes;
In the code you posted, all locations go to the Route component because they all contain /. So the switch will never hit the Redirect.
In my example, the Redirect will get hit when the location is exactly /. It will then redirect the user to /main, where the Switch will hit the Route which loads your MainContainer component.

Related

components in index file gets render in every route in react

I'm new to react I'm using react-router ^6.0.2 and my problem is I created a component for the router then I called this component in the index file but when I add another component to the index it gets rendered in all the routes with the navbar in every single route I want the navbar to be rendered in all components but not the other component in the index file sorry for my bad English
index file:
import React from "react";
import ReactDOM from "react-dom";
import "../src/css/style.css";
import Router from "./Components/Router";
const App =()=>{
return(
<div>
<Router/> {/* i want this to get renderd in all routes */}
<Test/> {/*i want this to get renderd only in home page */}
</div>
)
}
ReactDOM.render(<App/>,document.getElementById("root"));
router component :
import { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Routes, Route} from "react-router-dom";
import NavBar from "./NavBar";
import About from "./About";
import Product from "./Product"
import Sp from "./Sp"
import Contact from "./Contact"
class Router extends Component{
render(){
return(
<BrowserRouter>
<NavBar/>
<Routes>
<Route path="about" element={<About/>}/>
<Route path="product" element={<Product/>}/>
<Route path="sp" element={<Sp/>}/>
<Route path="contact" element={<Contact/>}/>
</Routes>
</BrowserRouter>
)
}
}
export default Router
As it is right now, you don't have a home page. A home page is essentially a <Route path='/' /> Make one, and put your <Test/> component in it. Let me know if you're still struggling.
Put test component in routes component and send it's path as "home"

React Router won't load pages without first loading the home page

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')
);

Error: <Route> elements are for router configuration only and should not be rendered in react-router v4

Tried to upgrade react-router from 2 to 4 and broke it and now cant render my app.
getting various errors (the most recent is: <Route> elements are for router configuration only and should not be rendered)
I have also had the error where my ./ route renders fine but every other route blows up when I refresh and says Cannot GET /randomRoute
I am creating a react app and my main index.js file (where I include ReactDOM.render) also includes the routes and looks like so:
import React from 'react';
import ReactDOM from 'react-dom';
import { Route } from 'react-router';
import { BrowserRouter as Router, Match, HashRouter } from 'react-router-dom'
import Header from './components/header';
import './index.scss';
class App extends React.Component {
render() {
return (
<Router history={HashRouter}>
<div>
<Route path={"/"} component={Header} />
</div>
</Router>
);
}
}
ReactDOM.render(<App />,
document.getElementById('content'));
why would I be getting that current error and can anyone give me a simple start to the basics I need to include just to get routing working? it worked in version 2 but I wanted to upgrade and now cant get it working again
The problem is that you are specifying history object as a Router type.
From the Documentation
A <Router> that uses the hash portion of the URL (i.e.
window.location.hash) to keep your UI in sync with the URL.
This is similar to what you would do when you specify history as
hashHistory in Router v2.
Also, history object has been seprated into a seprate package from v4 onwards.
You can either make use of BrowserRouter or HashRouter to render your Routes.
Change your Route Configuration to below if you want to use BrowserRouter which is <Router> that uses the HTML5 history API (pushState, replaceState and the popstate event) to keep your UI in sync with the URL.This is similar to what you would do when you specify history as browserHistory in Router v2.
Also you need to import Route from 'react-router-dom'.
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Match, Route} from 'react-router-dom'
import Header from './components/header';
import './index.scss';
class App extends React.Component {
render() {
return (
<Router >
<div>
<Route path={"/"} component={Header} />
</div>
</Router>
);
}
}
Well, in react router v4 the API is different. You have to define it in your index.js file like this,
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<div>
<Switch>
<Route path="/path/one" component={ComponentOne} />
<Route path="/path/two" component={ComponentTwo} />
<Route path="/" component={IndexComponent} />
</Switch>
</div>
</BrowserRouter>
</Provider>
, document.querySelector('.container'));
Make sure the order is important here. Put the most generic one at last. Hope this helps. Happy coding !

React router basic implementation

I am trying to implement React router and I have a class called App from which I want to call ExpenseApp. For ExpenseApp to work, it requires 'data' which I want to pass. Also, my first page of get loaded should be ExpenseApp. As far as I understood react-router, the class name to be specified in the '/' path is the first page to be loaded. The question is how can I pass data from react router to the component.
import React from 'react'
import ReactDOM from 'react-dom'
import {ExpenseApp} from './expense-app.js'
import {Switch, BrowserRouter, Route} from 'react-router-dom'
import {FullBlog} from './FullBlog.js'
var data=[
{
"Author":"Dan Brown",
"Book":"Inferno"
},
{
"Author":"Jeffrey Archer",
"Book":"Be careful what you wish for"
},
{
"Author":"Paulo Coelho",
"Book":"The Alchemist"
}
];
class App extends React.Component{
render(){
return(
<Router>
<Route path='/' component={ExpenseApp}/>
<Route path='fullblog' component={FullBlog}/>
</Router>
)
}
}
ReactDOM.render(<App/>, document.getElementById('container'))
And normally when I was displaying the component without using the react-router, I was doing something like
I am still confused with the concepts of react-router, how can I implement this?
maybe you can try this one :
<Router>
<Route exact path='/' render={() => <ExpenseApp data={data} />}/>
<Route path='fullblog' component={FullBlog}/>
</Router>
this is using react router v4, hope can solve your issue :)
As far as I know, you usually would want to fetch data from within the component, but if it is not possible or you do not want to do this, you could try using decorateComponentWithProps (https://github.com/belle-ui/decorateComponentWithProps)
import decorateComponentWithProps from 'decorate-component-with-props';
// ...
<Route path='/' component={decorateComponentWithProps(ExpenseApp, {data})} />
Given that the ExpenseApp's prop name is data
Edit: As found out in the comments, you also need to change
import {Switch, BrowserRouter, Route} from 'react-router-dom'
to
import {Switch, BrowserRouter as Router, Route} from 'react-router-dom'
For the code to work, or you can also change the usage of <Router /> to <BrowserRouter />

Pagination issue using React Router v4.1

I'm migrating a site in ASP.NET MVC to REACT. And for pagination i have created a component in React.
Issue i'm facing is with Routing for the pagination URLs. React Router is not able to detect that the URL is different when i click on a pagination URL
Let me explain:
app.js code:
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore, applyMiddleware} from 'redux';
import allReducers from '../reducers/index';
import {Provider} from 'react-redux';
import ReduxPromiseMiddleware from 'redux-promise';
import { BrowserRouter, Route } from 'react-router-dom';
import Main from './main';
import Layout from './layout';
const app = document.getElementById('root');
const store = createStore(allReducers, applyMiddleware(ReduxPromiseMiddleware));
ReactDOM.render(<Provider store={store}>
<BrowserRouter>
<Layout>
<Main/>
</Layout>
</BrowserRouter>
</Provider>
,app);
Main component render:
render(){
return(
<main>
<Switch>
<Route exact path='/' component={HomePage}/>
<Route path='/posts' component={PostsRouter} />
<Route path='/studies' component={StudiesPage} />
</Switch>
</main>
);
}
PostsRouter component:
const PostsRouter = () => (
<Switch>
<Route exact path='/posts' component={PostsPage} />
<Route path='/posts/:page' component={PostsPage} />
</Switch>
);
For both /posts and /posts/2 i need the component to be PostsPage.
Lets say i'm at /home. Now i click a posts link and URL changes to /posts. Now if i click /posts/2 link, nothing happens. React Router doesn't detect that the URL is different.
And a weird thing i noted is that if i change the component:
<Route path='/posts/:page' component={PostsPage} />
to
<Route path='/posts/:page' component={StudiesPage} />
then React Router routes me to StudiesPage component if i click on /posts/2 link when i'm on /posts URL.
May be i'm missing something obvious. But i haven't been able to figure out a way after lots of attempts.
I suspect Sergey's comment was right, that's what my problem ended up being. I was fetching data within componentDidMount() but didn't realise that in order to actually update it with new data when the next page link was clicked, I needed to do the same thing inside componentWillReceiveProps(). You can see my full source here but the biggest key part was this:
componentWillReceiveProps(nextProps) {
this.setState({
loaded: false
});
this.fetchMediaItems(nextProps.match.params.page);
}
componentDidMount() {
this.fetchMediaItems(this.props.match.params.page);
}
componentWillReceiveProps() receives the new properties, including page number, when you click on the link to page 2, so you need to do whatever inside there to update with the new state.

Categories

Resources