I have a route configuration that looks like this (showing only the parts that I think may be relevant):
var React = require('react'); var Router = require('react-router'); var { Route, DefaultRoute, NotFoundRoute } = Router; var routes = ( <Route handler={AppHandler}> <DefaultRoute handler={HomeHandler}/> <Route name='home' path='/home' handler={HomeHandler}/> <Route name='settings' path='/settings/?:tab?' handler={SettingsHandler}/> <NotFoundRoute handler={NotFoundHandler}/> </Route> ); Router.run(routes, Router.HistoryLocation, function (Handler) { React.render(<Handler/>, document.getElementById('application')); });
Now, on my Settings react file, I have the following:
var Settings = React.createClass({ mixins: [Router.State], render: function() { ... } });
If I access the host.local/settings
and log this.getParams()
everything works fine and the file renders showing me Object {tab: undefined}
in the console. But as soon as I try host.local/settings/user
- where I expected the console to return something like Object {tab: 'user'}
-, the whole thing crashes somewhere and just starts throwing Uncaught SyntaxError: Unexpected token <
in the console.
React is still young and therefore the errors are rather vague in many situations.
I've followed the specifications provided on the Path Matching Guide and it seems pretty standard, so I can only assume it's a problem with react-router itself or am I missing something?
tl;dr: It's not a problem with react-router.
Long version:
Apparently, it turns out the issue is not on ReactJS neither React-Router themselves. It involves mostly a bug on gulp-webserver (which I'm using for developing using proxies to connect separate projects running in parallel) and triggers an error when URLs are typed directly on the browser instead of being accessed through a link.
I did a test and it works fine when navigating, but crashes when accessed directly as described on this github issue, which basically renders my functional deeplink tests unviable, but should work when in production.
tl;dr: It's not a problem with gulp-webserver either.
In my case, it was related to relative
and absolute
paths and not any issue with gulp-webserver as mentioned before. To be more specific, I had to make sure your script and CSS references were absolute so that it doesn't try to find them in the path you're typing in the URL.
e.g.:
You have two URLs: /settings
and /settings/account
. In that case, if you have your script inclusion in the fallback file being something like <script src="scripts/main.js"></script>
, the server will return a 404 for it, since there's no file in /settings/scripts/main.js
.
Dumb of me, but in case anyone else falls for that, I hope this helps.
React Router is a standard library for routing in React. It enables the navigation among views of various components in a React Application, allows changing the browser URL, and keeps the UI in sync with the URL. Let us create a simple application to React to understand how the React Router works.
At the core of every React Router application should be a router component. For web projects, react-router-dom provides <BrowserRouter> and <HashRouter> routers. The main difference between the two is the way they store the URL and communicate with your web server. A <BrowserRouter> uses regular URL paths.
The useParams hook is one of the several hooks in React router. It has been available in React router since version 5. You can use it to retrieve route parameters from the component rendered by the matching route. You will explore the React Router useParams hook and how to use it in this article.
React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.
Thanks for your analysis, it helped me to realize it wasn't an issue with React Router but my own paths.
I added <base href="/" />
into the <head>
of my index.html
and it worked (:
Edit for React Router 3:
Since early 2016, React Router will show a warning when you set <base>
:
Warning: Automatically setting basename using <base href> is deprecated and will be removed in the next major release. The semantics of <base href> are subtly different from basename. Please pass the basename explicitly in the options to createHistory
It's better to do something like this instead:
const history = useRouterHistory(createHistory)({ basename: '/' });
I am not encountering the error that you're seeing. It seems like your code is all right, so it's probably something that you didn't paste.
giving the information, I've build a quick project according to your spec and here's my setup
'use strict'; var React = require('react'), Router = require('react-router'), AppHandler = require('./pages/app.js'), HomeHandler = require('./pages/home.js'), SettingsHandler = require('./pages/setting.js'), NotFoundHandler = require('./pages/not-found.js'), Route = Router.Route, NotFoundRoute = Router.NotFoundRoute, DefaultRoute = Router.DefaultRoute, Routes; Routes = ( /* jshint ignore:start */ <Route handler={AppHandler}> <DefaultRoute handler={HomeHandler}/> <Route name='home' path='/home' handler={HomeHandler}/> <Route name='settings' path='/settings/?:tab?' handler={SettingsHandler}/> <NotFoundRoute handler={NotFoundHandler}/> </Route> /* jshint ignore:end */ ); Router.run(Routes, Router.HistoryLocation, function (Handler, state) { React.render(<Handler/>, document.body); });
I'm skipping the home and not found since those are not the problem, here's my setup in settings.js
'use strict'; var React = require('react') Router = require('react-router'); var Setting = React.createClass({ mixins: [Router.State], componentDidMount: function() { //console.log(this.getParams()); }, render: function() { /* jshint ignore:start */ console.log(this.getParams()); return ( <div>this is setting</div> ); /* jshint ignore:end */ } }); module.exports = Setting;
hope these will help
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With