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>
Related
I want to insert via URL some data like an ID.
Example: somewebsite.com/movie/(ID_GOES_HERE)
But i can't understand how to make it happen. I want the data to go in the url and i want to retrieve it in movie.js, how do i do that?
I installed router dom in the app.
import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Switch, Route} from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import App from './App';
import MovieDetail from './Movie';
const history = createBrowserHistory();
ReactDOM.render(
<Router history={history}>
<Switch>
<Route exact path='/' component={App}/>
<Route path='/movie' component={Movie}/>
</Switch>
</Router>,
document.getElementById('root')
);
It is expected to show the ID in Movie.
From react-router documentation:
./App
<Route path="/movie/:movie_id" component={Movie} />;
./Movie
// All route props (match, location and history) are available to Movie
export function Movie(props) {
return <h1>Show movie {props.match.params.movie_id}!</h1>;
}
I am working on my first meteor/react application and I am trying to use react-router. However, when I try to run the app, I can't seem to import the renderRoutes function.
I am trying to follow along with the router part here:
https://guide.meteor.com/react.html
The router lives in myapp/client/lib/router.js. Here is my router code:
import React from 'react';
import { Router, Route, Switch } from 'react-router';
import createBrowserHistory from 'history/createBrowserHistory';
import {Home} from '../home/home.js';
import {Login} from '../login/login.js';
import {Connect} from '../connect/connect.js';
const browserHistory = createBrowserHistory();
export const renderRoutes = () => (
<Router history={browserHistory}>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/connect" component={Connect}/>
</Switch>
</Router>
);
I have a meteor.startup() function in myapp/server/main.js, this is all I have in there:
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import { renderRoutes } from '../client/lib/router.js';
Meteor.startup(() => {
render(renderRoutes(), document.getElementById('App'));
});
When I try to run meteor run, here's what I see:
Error: Cannot find module '../client/lib/router.js'
Why? Any help is appreciated!
It is because your router is located in
myapp/client/lib/router.js
whereas your main file is located in
myapp/server/main.js
So unless you intend to implement server-side-rendering, you may move the second code to
myapp/client/main.js
This is due to Meteor's project-structure awareness. If a file is contained in a folder, named client or server it will only be available in this environment.
More to read in the guide: https://guide.meteor.com/structure.html#special-directories
Failed prop type: The prop history is marked as required in Router, but its value is undefined.
Index.js
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import Sstore from './store/configureStore.js';
import routes from './routes';
import {loadMovies} from './actions/movieActions.js';
const store = Sstore;
store.dispatch(loadMovies());
render(
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>,
document.getElementById('app')
);
Route.js
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import Home from './components/Home.js';
export default (
<Route path="/" component={Home}>
</Route>
);
This is the correct link to react-router-redux v4 example. You have to use ConnectedRouter from react-router-redux and pass history. I configured my project yesterday based on this example and it works fine.
In React router v4, your configuration should be something like below.
import { BrowserRouter, Route, Switch } from 'react-router-dom';
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<div>
<Switch>
<Route path="/api/:id" component={ComponentOne} />
<Route path="/" component={Home} />
</Switch>
</div>
</BrowserRouter>
</Provider>
The API has been changed since the previous version. Also note that the order matters. Keep the most specific paths at the top.
In my project, I get rid of this type of error in two steps:
step in to import import createBrowserHistory from 'history/createBrowserHistory'; and declaring const customHistory = createBrowserHistory(); like this:
import { BrowserRouter as StaticRouter, Router, Switch, Route, Link } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const customHistory = createBrowserHistory();
It looks like that it is necessary to add history attribute to the Router:
<Router history={customHistory}>
<div>
<Link to={'/.../' + linkName1}>
{itemName1}
</Link>
<Link to={'/.../' + linkName2}>
{itemName2}
</Link>
</div>
I have just started using react-router V4 and I want to know how to get current location of router
This is my source code
import {Meteor} from 'meteor/meteor';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory'
import {Route, BrowserRouter as Router, Switch} from 'react-router-dom'
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/signUp';
import Link from '../imports/ui/link';
import Login from '../imports/ui/login';
import NotFound from '../imports/ui/notFound';
const history = createHistory();
const unauthenticatedPages = ['/', '/signup'];
const authenticatedPages = ['/links'];
const routes = (
<Router history={history}>
<Switch>
<Route exact path="/" component={Login}/>
<Route exact path="/signup" component={Signup}/>
<Route path="/links" component={Link}/>
<Route component={NotFound}/>
</Switch>
</Router>
);
Tracker.autorun(() => {
const unlisten = history.listen((location, action) => {
// location is an object like window.location
console.log(action, location.pathname, location.state)
})
const isAuthenticated = !!Meteor.userId();
console.log('location: ', location.pathname);
//const pathName =
});
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
I tried according to react-router documentation to use history but I didn't get the location.
How to get current location of a route?
I don't use redux and I will appreciate an answer without it.
Thanks, Michael.
You can use the withrouter HOC for this. It will re-render the wrapped component anytime the route changes. Here's an example -
import {Meteor} from 'meteor/meteor';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory'
import {Route, BrowserRouter as Router, Switch} from 'react-router-dom'
import {withRouter} from 'react-router'
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/signUp';
import Link from '../imports/ui/link';
import Login from '../imports/ui/login';
import NotFound from '../imports/ui/notFound';
const history = createHistory();
const unauthenticatedPages = ['/', '/signup'];
const authenticatedPages = ['/links'];
const
ChangeTracker = withRouter(({match, location, history}) => {
console.log(action, location.pathname, location.state);
return false;
}),
routes = (
<Router history={history}>
<Switch>
<Route exact path="/" component={Login}/>
<Route exact path="/signup" component={Signup}/>
<Route path="/links" component={Link}/>
<Route component={NotFound}/>
</Switch>
<ChangeTracker />
</Router>
);
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
Excellent help thanks - to keep live updating whether you're on an authenticated page or not, you could modify ChangeTracker as follows:
const ChangeTracker = withRouter(({match, location, history}) => {
const pathName = location.pathname;
isUnauthenticatedPage = unauthenticatedPages.includes(pathName);
isAuthenticatedPage = authenticatedPages.includes(pathName);
return false;
});
and your Tracker.autorun could look like:
Tracker.autorun(()=>{
const isAuthenticated = !!Meteor.userId();
if (isAuthenticated){
if (isUnauthenticatedPage){
history.push('/links');
}
}else{
if (isAuthenticatedPage) {
history.push('/');
}
}
});
You can get your current location from react router v4 by history.location and for the pathname you can use history.location.pathname. you can find more details about it in the official react router docs on githubReact Router Training.
So your code should be like this:
import {Meteor} from 'meteor/meteor';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory'
import { Route, Router, Switch } from 'react-router-dom'
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/signUp';
import Link from '../imports/ui/link';
import Login from '../imports/ui/login';
import NotFound from '../imports/ui/notFound';
const history = createHistory();
const unauthenticatedPages = ['/', '/signup'];
const authenticatedPages = ['/links'];
const routes = (
<Router history={history}>
<Switch>
<Route exact path="/" component={Login}/>
<Route exact path="/signup" component={Signup}/>
<Route path="/links" component={Link}/>
<Route component={NotFound}/>
</Switch>
</Router>
);
Tracker.autorun(() => {
const isAuthenticated = !!Meteor.userId();
const pathname = history.location.pathname;
//Now you can do whatever you want here
});
Important! passing history as props to BrowserRouter makes warning because by default BrowserRouter uses its version of history and ignores the history you passed, so to prevent this warning you should use { Router } from 'react-router-dom' rather than BrowserRouter and everything works in the way you expect.
I am a reactjs beginner and I am trying react-router.
Here is my code.
Main.js
import React from 'react';
import ReactDOM from 'react-dom';
import ReactRouter from 'react-router';
var Route = ReactRouter.Route
var Router = ReactRouter.Router;
var browserHistory = ReactRouter.browserHistory;
var IndexRoute = ReactRouter.IndexRoute;
import App from './App.jsx';
import Home from './Home.jsx';
import About from './About.jsx';
import Contact from './Contact.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 code: SCRIPT5007: Unable to get property 'route' of undefined or null reference. Thanks