I'm using react to recreate a simple route example. Currently only App component is being displayed even if I type anything else after 'localhost:3000/#/' I want to display App component when 'localhost:3000/#/' is called and a Whoops404 component for wildcard. However if I swap the route lines and write Whoops404 component first then every URI shows the Whoops404 component. Whatever route is written first starts showing in browser for every URI. Please let me know what am I missing?
My index.js code is as follows
import React from 'react'
import {render} from 'react-dom'
import {App} from './components/App'
import {Whoops404} from './components/Whoops404'
import {BrowserRouter, Switch, Route} from 'react-router-dom'
window.React = React
render(
<BrowserRouter>
<div>
<Switch>
<Route path = '/' component = {App}/>
<Route path = '*' component = {Whoops404}/>
</Switch>
</div>
</BrowserRouter>,
document.getElementById('react-container'));
You need to add 'exact' keyword in your Route
` <Switch>
<Route exact path = '/' component = {App}/>
<Route exact path = '*' component = {Whoops404}/>
</Switch>`
Related
React router switch works fine when I using Redirects, Navlinks or other library staff.
The problem is in function loadOrderPage. When its fired, window location changes OK but page not re-render accordingly to react-router switch rules, so component for '/order' doesn't render after this function complete.
here is my simple react class
Live working example here: https://codesandbox.io/s/delicate-wildflower-sdvd4?file=/src/App.js
import React from "react";
import {
BrowserRouter as Router,
Redirect,
Route,
Switch,
} from "react-router-dom";
import Startpage from "./components/startpage";
import Orderpage from "./components/orderpage";
import { withRouter } from "react-router";
class App extends React.Component {
.......
loadOrderPage = () => {
this.props.history.push("/order");
};
render() {
return (
<Router>
<Switch>
<Route path="/order">
<Orderpage />
</Route>
<Route path="/">
<Startpage/>
</Route>
</Switch>
</Router>
);
}
}
export default withRouter(App);
Whats wrong? I want to able change window location in functions and waiting that react router would render correct components under switch rules. May be its more suitable methods are available?
You cannot have two defined, both in your index.js and in your App.js. Remove the <Router></Router> from your App.js.
Make sure to add exact to your <Route />.
<Route exact path="/order">
<Orderpage />
</Route>
<Route exact path="/">
<Startpage/>
</Route>
I'm currently running into an issue where if a user types in localhost:3000/resume, it would default back to localhost:3000. It works just fine when I click the button I wrote to specifically navigate to the resume page, but I want it so that if they type in that specific path in the URL they should be able to visit that page without having to start from the landing page and navigating to there. Here is my code that contains the Router
App.js
import React from 'react';
import './App.css';
import LandingPage from './pages/LandingPage/LandingPage';
import {Route,Router, Redirect} from 'react-router-dom';
import history from './history';
import Projects from './pages/Projects/Projects';
import Experiences from './pages/Experiences/Experiences';
import Resume from './pages/Resume/Resume'
function App() {
return (
<div className="App">
<Router history = {history}>
<Route path = "/" component = {LandingPage} exact/>
<Route path = "/projects" component = {Projects} exact/>
<Route path = "/experiences" component = {Experiences} exact/>
<Route path = "/resume" component = {Resume} exact/>
<Redirect to = "/"/>
</Router>
</div>
);
}
export default App;
history.js
import {createBrowserHistory} from "history";
export default createBrowserHistory()
Thanks #Shawn_Yap, here's the new App.js code in case anyone else has created the same error I did.
You need a switch otherwise it seems to render all routes then redirect back to the landing page. Here's the documentation for further reference. Switch Documentation React Router Dom
App.js
import React from 'react';
import './App.css';
import LandingPage from './pages/LandingPage/LandingPage';
import {Route,Router, Switch,Redirect} from 'react-router-dom';
import history from './history';
import Projects from './pages/Projects/Projects';
import Experiences from './pages/Experiences/Experiences';
import Resume from './pages/Resume/Resume'
function App() {
return (
<div className="App">
<Router history = {history}>
<Switch>
<Route path = "/projects" component = {Projects} exact/>
<Route path = "/experiences" component = {Experiences} exact/>
<Route path = "/resume" component = {Resume} exact/>
<Route path = "/" component = {LandingPage} exact/>
<Redirect from="*" to = "/"/>
</Switch>
</Router>
</div>
);
}
export default App;
I'm migrating to ReactRouter v4 and it's just been proving a hassle to me. I have a file in app.js in which i'm trying to setup a simple routing system.
import React, { Component } from 'react';
import { Router, Route, IndexRoute, hashHistory, Redirect } from 'react-router';
import LoginPage from './LoginPage';
import NavigationBar from './NavigationBar';
class App extends Component {
render() {
return (
<Router history={history}>
<Route exact path='/' component={NavigationBar}></Route>
<Route exact path='/login' component={LoginPage}></Route>
</Router>
);
}
}
The code compiles perfectly well, but for some reason on the browser, the navigation bar is shown instead of the login page when the url is localhost:3000/login
The image of the nagivation bar showing instead of the login
I intended the login to be shown at /login and the navigation bar to be shown at /, but instead the navigation bar is shown at both /login and /.
I've been following the examples on the react-router training guide here, and I can't seem to figure out what I'm doing wrong.
Maybe it's just a typo in your post here, but you're extending Compoent instead of Component. I would guess you'd see worse issues than getting the wrong component if that was happening in your code.
I prefer BrowserRouter (I don't have to support legacy browsers), but I got your code working like this:
import React, { Component } from 'react';
import { Route } from 'react-router';
import { HashRouter as Router } from 'react-router-dom';
import LoginPage from './LoginPage';
import NavigationBar from './NavigationBar';
class App extends Component {
render() {
return (
<Router>
<div>
<Route exact path='/' component={NavigationBar}></Route>
<Route exact path='/login' component={LoginPage}></Route>
</div>
</Router>
);
}
}
You'll have to install react-router-dom for this code to run.
Visiting http://localhost:3000/#/login, I get the Login component. If you change HashRouter to BrowserRouter, you can see your component render at http://localhost:3000/login.
I'm very new to ReactJS. I was trying some tutorials to do routing but end up with errors where the "browserHistory" was undefined. The code and error message is as below.
Main.js
'use strict';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, IndexRoute, hashHistory,browserHistory} from 'react-router';
import App from './App.jsx';
import {Home,About,Contact} from './App.jsx';
ReactDOM.render((
<Router history = {browserHistory}>
<Route path = "/" component = {App}>
<IndexRoute component = {Home} />
<Route path = "home" component = {Home} />
<Route path = "about" component = {About} />
<Route path = "contact" component = {Contact} />
</Route>
</Router>
), document.getElementById('app'))
Error Message from browser console
Warning: Failed prop type: The prop history is marked as required in
Router, but its value is undefined.in Router
Kindly let me know if the implementation is out-of-date or if I have missed out any libraries to face this problem
I think I have found the reason, the new react-router does not support browserHistory anymore. To achieve the same goal I have used the following code.
import createBrowserHistory from 'history/createBrowserHistory';
const history = createBrowserHistory();
Can you try useRouterHistory:
import { useRouterHistory } from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';
const createAppHistory = useRouterHistory(createBrowserHistory);
const history = createAppHistory({
parseQueryString: parse,
stringifyQuery: stringify
})
<Router history={history}/>
React Router v4 changed things. They made separate top level router elements. Replace <Router history={hashHistory}> with <HashRouter> in your code.
import {HashRouter,Route} from 'react-router-dom';
<HashRouter>
<Route path = "/" component = {App} />
</HashRouter>
I'm getting started with Walmart's react/redux/react-router/isomorphic boilerplate called electrode and I'm having trouble adding multiple routes. When I add the 2nd route it seems to do nothing and linking and pushing to the other routes does not change the page.
http://www.electrode.io/docs/get_started.html
https://github.com/electrode-io/electrode-redux-router-engine
Here's what the single route in the boilerplate looked like
// routes.jsx
import React from "react";
import {Route} from "react-router";
import Home from "./components/home";
export const routes = (
<Route path="/" component={Home}/>
);
and here's what I changed it to
import React from "react";
import {Route, IndexRoute} from "react-router";
import Home from "./components/home";
import Foo from "./components/foo";
export const routes = (
<Route path="/" component={Home}>
<Route path="/foo" component={Foo}/>
</Route>
);
I couldn't put the routes side by side because that gave me an error saying that jsx can't have two elements side-by-side so I had to nest it. The react router examples I see online seem to assume a root app component. Looking at the electrode router redux sample, they set the root component to "Page". What is the "Page" component? My questions are
Why doesn't my 2nd route work?
Should I be using an IndexRoute?
Do I need to create a root component for the root route? If so what does that component look like?
Here's the app.jsx code
//
// This is the client side entry point for the React app.
//
import React from "react";
import {render} from "react-dom";
import {routes} from "./routes";
import {Router} from "react-router";
import {createStore} from "redux";
import {Provider} from "react-redux";
import "./styles/base.css";
import rootReducer from "./reducers";
//
// Add the client app start up code to a function as window.webappStart.
// The webapp's full HTML will check and call it once the js-content
// DOM is created.
//
window.webappStart = () => {
const initialState = window.__PRELOADED_STATE__;
const store = createStore(rootReducer, initialState);
render(
<Provider store={store}>
<Router>{routes}</Router>
</Provider>,
document.querySelector(".js-content")
);
};
A few things...
You can avoid the "side by side jsx" warning by wrapping your routes in an empty route or returning an array.
// return nested routes
return (
<Route path="/">
<Route path="foo" component={Foo}/>
<Route path="bar" component={Bar}/>
</Route>
)
// return array, must use keys
return [
<Route key="foo" path="/foo" component={Foo}/>,
<Route key="bar" path="/bar" component={Bar}/>
]
If you want to nest routes, you need to give way to the child component by adding {this.props.children} to the parent component's render.
If you want truly separate routes that are not nested, it shouldn't be a child of the first route. I don't think adding an IndexRoute would provide any benefit unless you want some UI that is top level for all routes (like rendering a header, sidebar, etc).