404 not found for nesting routes in react router v4 - reactjs

In my app, I have the routes
/auth/login
/auth/register
And the common parts in page are placed in Auth.jsx, use Router to /auth/login and /auth/regster
But /auth/login/xxx will also match /auth/login
The only solution to fix is to add exact, Switch and Error Route everywhere
Is any other solutions for this avoiding writing too many Error Routes?
Codes Following...
App.jsx
import React from 'react'
import { render } from 'react-dom'
import { Route, Switch } from 'react-router-dom'
import Error from './Error'
import Home from './Home/Home'
import Auth from './Auth/Auth'
export default class App extends React.Component {
render () {
return (
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/auth" component={Auth}/>
<Route component={Error}/>
</Switch>
)
}
}
Auth.jsx
import React from 'react'
import { render } from 'react-dom'
import { Route, Link } from 'react-router-dom'
import Login from './Login'
import Register from './Register'
export default class Auth extends React.Component {
render () {
return (
<div>
<div>Auth works</div>
<div>
<Link to={`${this.props.match.url}/login`}>LOGIN</Link>
<Link to={`${this.props.match.url}/register`}>REGISTER</Link>
</div>
<Route exact path={`${this.props.match.url}/login`} component={Login}/>
<Route exact path={`${this.props.match.url}/register`} component={Register}/>
</div>
);
}
}

Related

How to stop random links from opening with react-router?

I am new to React and practicing with an online website for repairing appliances. I have used react-router and created all my routes in a separate file.
I have a problem though, I can open any link from the address bar like:
http://localhost:3000/<randomword>
I only want routes to be opened that I have declared in my routes component while if I type http://localhost:3000/something, I get an empty page with my header and footer in it.
here are my codes:
Index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from "react-router-dom";
import Routes from './Routes';
import './index.css';
const App = () => {
return(
<BrowserRouter>
<Routes />
</BrowserRouter>
)
}
ReactDOM.render(<App/>,document.getElementById('root'));
App.js:
import React, {Component} from 'react';
import { Route, BrowserRouter } from 'react-router-dom';
import Layout from './Containers/Layout';
import LandingPage from './Containers/Pages/LandingPage';
import About from './Containers/Pages/About';
import Cities from './Containers/Pages/Cities';
import Discount from './Containers/Pages/Discount';
class Routes extends Component {
render(){
return (
<div>
<Layout>
<BrowserRouter>
<Route path="/" render={props => <LandingPage {...props} />} exact component={LandingPage}/>
<Route path="/About" component={About}/>
<Route path="/Cities" component={Cities}/>
<Route path="/Discount" component={Discount}/>
</BrowserRouter>
</Layout>
</div>
);
}
};
export default Routes;
Layout.js:
import React, { Component } from 'react';
import Header from "./Layouts/Header";
import Footer from './Layouts/Footer';
import './Layout.css';
export default class Layout extends Component {
constructor(){
super();
this.state= {
}
}
render() {
return (
<div className="page-container">
<Header/>
<div className="content-wrap">
{this.props.children}
</div>
<Footer/>
</div>);
}
}
Can someone help me figure out how I should stop random random pages to be opened from addressbar?
Just want to start by saying I'm completely self-taught with React so I apologize if this answer is incorrect. However, in my experience with react-router I always have a Switch inside of my BrowserRouter. So your Routes class in app.js should something like this:
class Routes extends Component {
render(){
return (
<div>
<Layout>
<BrowserRouter>
<Switch>
<Route path="/" render={props => <LandingPage {...props} />} exact component={LandingPage}/>
<Route path="/About" component={About}/>
<Route path="/Cities" component={Cities}/>
<Route path="/Discount" component={Discount}/>
</Switch>
</BrowserRouter>
</Layout>
</div>
);
}
};
Just be sure you don't forget to update your imports to
import { Switch, Route, BrowserRouter } from 'react-router-dom';
import { Redirect } from "react-router-dom"
<Route path="/not-found" component={notFound-Component} />
<Redirect to="/not-found" />
This will always redirect you to 404 component if route is not present just make a 404 component and u should add the redirect at the end after all routes are defined

Simple React Component not rendering after Routing

I'm a beginner in React and I'm learning how to route. My page changes urls, but the view turns to a blank page. My index page is working fine. I don't have any console errors.
In Router.js
import React from "react";
import {
BrowserRouter,
Route,
Switch,
} from "react-router-dom";
import App from './App'
import SinglePriceGrid from './component/SinglePriceGrid'
function Router() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={App} />
<Route path="/single-page-grid" component={SinglePriceGrid} />
</Switch>
</BrowserRouter>
)
}
export default Router
In SinglePriceGrid.js
import React from 'react';
import '../css/SinglePriceGrid.css'
class SinglePriceGrid extends React.Component {
render() {
return (
<div className="SinglePriceGrid">
<h1>Hello Single Price Grid!</h1>
</div>
);
}
}
export default SinglePriceGrid;
edit: Added the imports I used
edit: Readded the Switch, but it did not solve the problem
keep the Routes inside Switch. Try this
import React from "react";
import {
BrowserRouter,
Route,
Switch,
} from "react-router-dom";
import App from './App'
import SinglePriceGrid from './component/SinglePriceGrid'
function Router() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={App} />
<Route path="/single-page-grid" component={SinglePriceGrid} />
</Switch>
</BrowserRouter>
)
}
export default Router
I'm really sorry, but the error is really humiliating. My path is wrong. I used "page" instead of "price" for the endpoint.

react router not rendering the component

I am trying to learn react route configuration. I am adding all the navigation link at one place which is entry point index.js and my expectation is when someone react to the path configured during navigation, respective component should be loaded in the briwser. I am adding all the route path in my entry file index.js as follow:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.js';
import { BrowserRouter, Route, hashHistory } from 'react-router-dom';
import AboutUs from './AboutUs.js';
import ContactUs from './ContactUs.js';
import {Switch} from 'react-router';
ReactDOM.render(
(<BrowserRouter>
<Switch>
<Route path="/" component={App}/>
<Route path="/about-us" component={AboutUs}/>
<Route path="/contact-us" component={ContactUs}/>
</Switch>
</BrowserRouter>)
, document.getElementById('app'));
app.js is as follows :
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
class App extends Component {
constructor(props){
super(props);
}
render() {
return (
<div>
<h1>React Router Tutorial</h1>
<ul role="nav">
<li><Link to="/about-us">About</Link></li>
<li><Link to="/contact-us">Contact</Link></li>
</ul>
</div>
)
}
}
export default App;
AboutUs.js is as follows :
import React, { Component } from 'react';
class AboutUs extends Component {
render(){
return(
<div>
AboutUs
</div>
);
}
}
export default AboutUs ;
ContactUs.js is as follows :
import React, { Component } from 'react';
class ContactUs extends Component{
render(){
return(
<div>
Contact Us
</div>
);
}
}
export default ContactUs;
But when I click on any of the link /about-us or /contact-us , it does not load any content and displays the same app.js as follows
Can someone please tell me why it is happening?
Switch renders the first route that it matches in the order that it is given.
<BrowserRouter>
<Switch>
<Route path="/about-us" component={AboutUs}/>
<Route path="/contact-us" component={ContactUs}/>
<Route path="/" component={App}/>
</Switch>
</BrowserRouter>
Because you had given '/' as first route, anything would match it and render App component.
I belive it's matching your first Route, the App one since you haven't specified that it should be exact.
You can do this :
<Switch>
<Route exact path="/" component={App}/> // it will match only for '/'
<Route path="/about-us" component={AboutUs}/>
<Route path="/contact-us" component={ContactUs}/>
</Switch>

React - inserting variable into Route path

I have an app that I am creating and am wondering how you would insert variables into the <Route path={insert variable here} component={myProfile}> I am trying to create a myProfile page and I am trying to get it so when they click onto the link, it redirects them to http://mywebsite.com/userId but when I try to create a Route with a variable in the path argument, it does not return the component I am trying to render when on that path.
routes.js
import { Meteor } from "meteor/meteor"
import React from "react";
import { withRouter, Switch, BrowserRouter, Route, Redirect, Link } from "react-router-dom";
import Login from "../ui/authentication/Login";
import Signup from "../ui/authentication/Signup";
import Home from "../ui/Home";
import { SubjectRoutes } from "../ui/subjectRoutes/subjectRoutes";
import AddNote from "../ui/AddNote";
import myProfile from "../ui/myProfile";
import NotFound from "../ui/NotFound";
export default class Routes extends React.Component{
renderSubjectRoutes(subjects){
return subjects.map((subject) => {
return <Route key={subject.name} path={subject.path} component={subject.component}/>
})
}
render(){
return (
<div>
<BrowserRouter>
<Switch>
<Login path="/login" />
<Signup path="/signup" />
<Route path="/" component={Home} exact/>
{this.renderSubjectRoutes(SubjectRoutes)}
<AddNote path="/addNote"/>
<myProfile path={Meteor.userId()} /> //<-- Here
<NotFound />
</Switch>
</BrowserRouter>
</div>
)
}
}
Menu.js
import { Meteor } from "meteor/meteor"
import React from "react";
import { withRouter, Link } from "react-router-dom";
import { SubjectRoutes } from "./subjectRoutes/subjectRoutes";
import AddNote from "./AddNote";
class Menu extends React.Component{
renderMenu(items){
return items.map((item) => {
return <p key={item.name}><Link to={item.path}>{item.name}</Link></p>
})
}
render(){
return(
<div>
<h1>Menu</h1>
{this.renderMenu(SubjectRoutes)}
<p><Link to="/addNote">Add a Note</Link></p>
<p><Link to={Meteor.userId()}>My Profile</Link></p>
</div>
)
}
}
export default withRouter(Menu)
You are creating way more work for yourself, and this is the wrong way to add variables to route. What you're looking to do is add params to your route. In your case, you would want it to look something like this.
<Route path="/user/:userId" />
The : is what denotes that it is a parameter, ready to render a path based on the userId. So if you went to route /user/123 - it would be able to render user 123's data.
Here's some documentation to help you out.
https://reacttraining.com/react-router/web/example/url-params

React routes not working properly

I think i got a problem using a very basic react router implementation.
When i load my "localhost:8080/dist/", it WORKS, load the header component that is being imported on App, and load the IndexRoute properly, but when i try to access "localhost:8080/dist/FPDV0200" or "localhost:8080/dist/FPDV0400" it dosnt work. Any clues?
app.component.tsx
import * as React from 'react';
import Header from '../header/header.component';
class App extends React.Component<any, any> {
render() {
return (
<div id="app">
<Header />
<div>
{this.props.children}
</div>
</div>
);
}
}
export default App;
app.component.tsx
import * as React from 'react';
import { Router, hashHistory, Route, IndexRoute } from 'react-router';
import App from '../components/structure/app/app.component';
import Home from '../pages/home/home';
import FPDV0200 from '../pages/FPDV0200/FPDV0200';
import FPDV0400 from '../pages/FPDV0400/FPDV0400';
const routes = (
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="FPDV0200" component={FPDV0200}/>
<Route path="FPDV0400" component={FPDV0400}/>
</Route>
</Router>
);
export default routes;
localhost:8080/dist/FPDV0200 - this url should work in case of usage browserHistory.
You use hashHistory, so your url should look like this
localhost:8080/dist#FPDV0200

Resources