Reputation: 120
When I enter localhost:8080
in my browser it displays App.js component. But when I navigate to localhost:8080/#/hello
it displays same App.js component instead of hello.js. localhost:8080/hello show "can not get localhost:8080/hello" . What is the problem with my code? I am using webpack and babel in my App.
//index.js
import React from 'react';
import ReactDOM, { render } from 'react-dom';
import { Provider } from 'react-redux';
import {store} from './public/store/store';
import App from './public/Components/App';
import Hello from './public/Components/hello';
import {
BrowserRouter as Router,
Route
} from 'react-router-dom';
//import './index.css'
render(
<Provider store={store}>
<Router>
<div>
<Route path="/" component={App}/>
<Route path="/hello" component={Hello}/>
</div>
</Router>
</Provider>,
document.getElementById('root')
)
//App.js
import React from 'react';
export default class App extends React.Component {
render() {
return (
<div>
<h1>React Js.</h1>
</div>
);
}
}
//hello.js
import React from 'react';
export default class Hello extends React.Component {
render() {
return (
<div>
<h1>Hello</h1>
</div>
);
}
}
Upvotes: 2
Views: 475
Reputation: 3908
There are a few things happening here, let me try to explain what's going wrong and how you can fix them.
http://localhost:8080/#/hello it displays the same App.js component instead of hello.js.
Because you are using BrowserRouter
instead of HashRouter (an older version, # is not working). The browser reads only the first part of your URL which is http://localhost:8080/
. The #
is similar when you route to a section of a page using the following.
<a href="#projects">Goto projects</a>
The above keeps the user on the same page but scrolls to the section <div id="projects"></div>
Don't use this, if your are using React Router V4 it's not what you are looking for.
http://localhost:8080/hello displays cannot get http://localhost:8080/hello
You probably don't have a dev server running that supports front-end routing. If you don't, basically what is happening is that by pressing enter you tell the SERVER to serve you page, http://localhost:8080/hello
. You don't want this, the server should be passive here and not serve you any other page then your main index.html. So, instead, you want the server to give you http://localhost:8080
and by doing so, it loads your main index.html and scripts, then react takes over, react-router checks the url and it then renders you the /hello route with the Hello
component.
In order to achieve this make sure you have webpack-dev-server
installed. You can do this by typing the following in the command line.
npm install webpack-dev-server --save-dev
Then add the following to your package.json
devServer: {
publicPath: '/',
historyApiFallback: true
}
// add the below line to the scripts section
"start:dev": "webpack-dev-server"
This basically tells the dev-server to re-route all requests to index.html, so react-router takes care of the routing. Here's more on Webpack-dev-server.
Then in your terminal run npm run start:dev
to start the development server.
I hope this all makes sense and with these guidelines you're able to make your code work. If not let me know ;)
NOTE: Alex has a good point as well. React Router v4 renders all routes that match. So, if the path is http://localhost:8080/hello
/
and /hallo
both match and will render. If you only want to render one, use exact
as Alex mentions, or wrap your routes in a <Switch>
component.
<Switch>
<Route path="/" component={App}/>
<Route path="/hello" component={Hello}/>
</Switch>
Here's what the react-router docs say.
Renders the first child or that matches the location
UPDATE:
After the OP uploaded a repo with the problem, the following was corrected to make the routes work. If anyone is interested, the fixed project is on GitHub.
Main points to make the project work:
react-router-dom
instead of react-router
app.get("/*", (req, res) => res.sendFile(__dirname + '/public/index.html'));
<Switch>
and <Route>
components to setup the routes as described in the question. See code here.Upvotes: 1
Reputation: 144
Try to use exact
directive:
<Route exact path="/" component={App} />
See API doc: https://reacttraining.com/react-router/web/api/Route/exact-bool
Upvotes: 0