Cannot read property 'location' of undefined in React Router example - reactjs

Trying to do the most simple example possible with React Router.
Every example I've looked at is very different and many include 20 page tutorials. I just want a simple root path to work:
...
<script src="https://unpkg.com/react#15.3.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom#15.3.2/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://npmcdn.com/react-router/umd/react-router.min.js"></script>
...
var insert_point = document.querySelector('#container');
var App = React.createClass({
render: function() {
return (
<div>
<h1>Simple SPA</h1>
<ul>
<li>Home</li>
<li>Stuff</li>
<li>Contact</li>
</ul>
<div>
</div>
</div>
)
}
});
ReactDOM.render(
<ReactRouter.Router>
<ReactRouter.Route path="/" component={App}>
</ReactRouter.Route>
</ReactRouter.Router>,
insert_point
);

Since you're in the browser, you'll need react-router-dom too, a separate package in v4. react-router only contains the core, but for the DOM bindings you need the former package:
<script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js"></script>
Then, get what you need from the global ReactRouterDOM. I find it easier just to use destructuring assignment to get what you need:
var { BrowserRouter, Route } = ReactRouterDOM;
Then you can do:
<BrowserRouter>
<Route exact path="/" component={App} />
</BrowserRouter>
The problem was that you weren't using the correct router -- for the web use BrowserRouter. Then, use Route and make sure to include the exact prop to only match the root route, in this case you can make Route self closing.

I suspect the problem is in how are you importing react router. When working with webpack I am using react-router-dom package and BrowserRouter
import { BrowserRouter as Router , Route, Switch} from 'react-router-dom'
Which are correct packages for V4. So at least I think you should use cdn that provides react-router-dom
also Try to use BrowserRouter instead of Router.
Aside from this, you can close your Route component immediately
<ReactRouter.Route path="/" component={App}/>
Also I do not understand your intentions with insertion_point as they are in your code.

Related

React-router-dom errror: `You should not use <Route> or withRouter() outside a <Router>`

I'm getting the You should not use <Route> or with Router() outside a <Router> error, but I'm already calling the route inside the router. There is my index.js:
import { BrowserRouter as Router, Route } from "react-router-dom";
import App from "./components/App";
const Wrapper = () => (
<Router>
<Route path="/:view?/" render={(props) => <App {...props} />} />
</Router>
);
ReactDOM.render(<Wrapper />, document.getElementById("root"));
Every route is inside App and therefore wrapped by the Router. Does anyone have any idea why it could be happening here?
Thank you for your help,
I found out what was happening. MDBReact Pro doesn't support the latest version of react-router-dom (what is kinda strange because their free version works well with it).
I had to downgrade react-router-dom to version 4.3.1.
Thank you, Shlang, for the hint. It helped me to figure out what was happening

Route doesn't match in react-router

I'm learning about react so I'm developing a personal blog with it. Moreover I use react-route but I've a problem because I don't understand why a route doesn't render (the route: /articule/:id). You can see the code in repository.
In the index.js define the route:
//it works
//index.js
const app = (
<Router>
<Switch>
<Route exact path="/" component={IRMBlog} />
<Route path="/articule/:id" component={IRMArticule}/>
</Switch>
</Router>
);
But If I move the line <Route path="/articule/:id" component={IRMArticule}/> to other file It doesn't work, why?
The file when I move the line of code is irm-articule-list.js
render() {
return (
<div className="column is-10 is-offset-1">
<IRMArticuleBox></IRMArticuleBox>
<IRMArticuleBox></IRMArticuleBox>
<Route path="/articule/:id" component={IRMArticule}/>
</div>
);
}
In the file irm-articule-box.js, I've <Link to="/articule/001">
Because application must have only one router, and router in react it's almost root component, one input for matching your urls
Like this.
import React, { Component } from 'react;
import { Link } from 'react-router-dom';
class articuleDetails extends Component {
render(){
return (
.....
<Link to="/articule/123"> articule name</Link>
...
)
}
}
Why do you want to move it?
In general you should know that Route must be inside a Router, and its job is to tell the browser which component to render when its path matches the location. It is not a hyperlink like the tag in HTML.
If your intention was hyperlink you should use <Link to="/">

Browser history issues in reactjs

I'm trying to run a project based on session timeout in reactjs.. But unfortunately an error occurs.. This is the error,
'react-router' does not contain an export named 'browserHistory'.
I think you're using React Router 4. It moves around some of those modules. You'll either need to migrate your code to use v4, or downgrade React Router in your package.json.
React router provides a migration guide here:
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/migrating.md
I think you are using react-router latest version. In new version history managed by internally. you can just use like and history is avaliable in your component props like props.history
import React from 'react';
import { Route } from 'react-router';
import { HashRouter, Switch } from 'react-router-dom';
let RootApp = () => {
return (
<div>
<HashRouter>
<Switch>
<PrivateRoute path='/admin' component={AdminRoute} />
<Route path='/login' component={LoginComponet}></Route>
<Route path='/**' component={LoginComponet}></Route>
</Switch>
</HashRouter>
</div>
);
}

React router component can't render its own children?

I'm trying to embrace the react-router 4 philosophy of having routing spread throughout the app instead of one central place. For brevity, <App> effectively spits out the following in its render():
<BrowserRouter>
<Link to='/' />
<Link to='/linkb' />
<Switch>
<Route exact path='/' component={ComponentA}>
<Route exact path='/linkb' component={ComponentB>
</Switch>
</BrowserRouter>
...
So far so good: the nav links help me to route to the corresponding components A and B and my 2 page app works fine.
The problem I'm having is that, inside componentB, now I want it to have its own child routes. Though these routes will be 'grandchildren' of <App/>, I see no reason why <App/> should know or care about them. I built this (surrounding content and css stuff mostly ripped out for clarity):
Component B
import React, { Component } from "react";
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import ComponentC from './ComponentC';
import ComponentD from './ComponentD';
export default class ComponentB extends Component {
constructor(props) { super(props);}
render() {
return (
<div>
<div>
<Link to='/linkb/c' className='btn'>link C</Link>
<Link to='/linkb/d' className='btn'>link D</Link>
</div>
{this.props.children}
<Switch>
<Route exact path="linkb/c" component={ComponentC}/>
<Route exact path="linkb/d" component={ComponentD}/>
</Switch>
</div>
);
}
}
When I click link C or link D, the url updates in the browser bar but nothing changes on the page / the new component is not rendered. What am I doing wrong?
OK - so the only way I've gotten this to work is to stop hardcoding the paths in my child components, and use the path segments passed in via react-router. Since these evaluate to the same thing (I think) I'm unsure why this fixes my problem, but it does:
<Link to={`${this.props.match.path}/c`}>link c </Link>
<Link to={`${this.props.match.path}/d`}>link d </Link>
And that works!! No idea why! If someone can explain why I'll accept their answer instead of mine.
update: appears to have been a case of absolute vs relative urls. Using props.match.path avoid that kind of confusion.

React-Router with React 13.3+

I can't figure out how to use any relatively recent (react 13+) version of React-router . The example on the current README suggests integrating it by rendering Router directly (with routes defined via child Route elements). Another official overview doc seems to advise using Router.run. The react-router examples use the former. None work for me: I get different errors depending on use:
When attempting to use react-router by rendering the Router element directly I get "Uncaught Error: Invariant Violation: A needs a valid Location”
When attempting to use react-router by running Router.run with routes, I get “Uncaught TypeError: Cannot read property 'toUpperCase' of null”
here is a simplified version of how to use it, this is using webpack for requires but this is irrelevant, if you have access to React and Router it will work.
var React = require('react');
var Router = require('react-router');
var DefaultRoute = Router.DefaultRoute;
var Route = Router.Route;
var RouteHandler = Router.RouteHandler;
var Link = Router.Link;
var Comp0 = require('./comp0.jsx');
var Comp1 = require('./comp1.jsx');
var Comp2 = require('./comp2.jsx');
var App = React.createClass({
render: function () {
return (
<div>
<div >
<li><Link to="comp0">comp0</Link></li>
<li><Link to="comp1">comp1</Link></li>
<li><Link to="comp2">comp2</Link></li>
</div>
<div>
<RouteHandler {...this.props}/>
</div>
</div>
);
}
});
var routes = (
<Route name="app" path="/" handler={App}>
<Route name="comp1" handler={Comp1}/>
<Route name="comp2" handler={Comp2}/>
<DefaultRoute name="comp0" handler={Comp0}/>
</Route>
);
Router.run(routes, function (Handler) {
React.render(<Handler />, document.body);
});
I'm using react-router version 0.13.3 with react version 0.13.3 (yes both are same). I use the Router.run() way so that the UI can be re-rendered on URL change. I'll show my code that works well for me, it's in ES6 (although shouldn't be too hard to derive ES5 from it):
import React from 'react';
import Router, { Route, DefaultRoute, NotFoundRoute, Redirect, Link } from 'react-router';
// Components
import App from './components/App.js';
import Home from './components/Home.js';
import SampleComponent from './components/SampleComponent.js';
const AppRoutes = (
<Route path="/" handler={App}>
<DefaultRoute name="home" handler={Home} />
<Route name="sample" handler={SampleComponent} />
</Route>
);
Router.run(AppRoutes, Router.HashLocation, (Root) => {
React.render(<Root />, document.body);
});
Make sure the components you specify in AppRoutes is accessible (by importing or requiring them). Also in this case I've used DefaultRoute for instance in AppRoutes - so if you're using similar configurations then make sure you have them available from the react-router export. Hope that's clear.
If you're still facing issues then share your code.
I have an existing example code that you can have reference with - https://github.com/iroy2000/react-reflux-boilerplate-with-webpack
For those who are interested, it is called "React Reflux Workflow Boilerplate", and it is a workflow framework that make life easier for developers by providing a development and production ready build process framework out of the box.

Resources