I am new to learning React and so far as I have been exploring its amazing. I have a quick question which is how can I display multiple modules such as "app.js" and "About.js" on one page? is this possible?
Here is some images that may help.
React App.js and About.js
React index.js
React js console error
Commonly in a react app, you will route based on different URLs.
The different 'modules' (also known as components) are typically defined in other JS files. See the HomePage and AboutPage files in the example below.
First, import the other pages.
Second, route to them given a path.
A common routing solution in React is React Router
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import HomePage from './pages/HomePage.js';
import AboutPage from './pages/AboutPage.js';
const MyApp = () => (
<BrowserRouter>
<Switch>
<Route path="/home" component={HomePage} />
<Route path="/about" component={AboutPage} />
</Switch>
</BrowserRouter>
);
Related
I have a multi-page application that doesn't use Node. It has a bunch of HTML and JavaScript files. I want to render React components in the application, which I found I am able to do with ReactDOM.render.
However, I am building out the React components separately in a project made with npx create-react-app. I can use npm run build which gives me a main.js file that contains a production ready version of all my components.
I can add this main.js file into my HTML files with a script tag to have my components render in my multi-page application.
However, the problem is that I notice when I run npm build, I get one main.js file that contains everything. This is not good because the app will run too slow if I have to load all of my React components in main.js file every time I go to a new page.
Instead, I am looking to only load the specific components I need for a page.
Example:
Let's say I had a test1 component and a test2 component.
Page1 has a script to use test1, so I only want to load test1 on Page1.
Page2 has a script to use test2, so I only want to load test2 on Page2.
Therefore, I need a test1.js file and a test2.js file after npm run build
How would I do this?
Sounds like a use case for Code Splitting.
If you want to split per-page with React Router you can do the following:
import React from "react";
import { render } from "react-dom";
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
const Home = React.lazy(() => import("./Home"));
const Contact = React.lazy(() => import("./Contact"));
render(
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>,
document.getElementById("root")
);
This should generate multiple JS files for different components (e.g. pages) when used with some standard build tools like create-react-app.
if someone could help that'd be great. I am following a react tutorial except at some point chrome went blank. When I inspect the page, nothing is in the body html tags. The code compiles and builds successfully though. I'm thinking it's a stupid typo or something, but I am no pro. Please let me know if you find my error!
Terminal On Build
you created the router but no routes. in app.js
import React from "react"
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom"
import Home from './pages'
function App () {
return (
<Router>
<Switch>
<Route exact path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
export default App;
Hi all it was a problem in one of my components. The lack of error messages made me think it had something to do with the construction of the app.
Here is my code for the index.js page:
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Route, Switch} from "react-router-dom"
import './css/bootstrap.min.css';
import './css/style.css';
// Pages
import Library from './pages/Library.js'
import Register from './pages/Register.js'
ReactDOM.render(
<div>
<Router>
<Switch>
<Route exact path="/" component={Library}/>
<Route exact path="/library" component={Library}/>
<Route exact path="/register" component={Register}/>
</Switch>
</Router>
</div>,
document.getElementById('root')
)
When I run npm start I get the application as desired. localhost:3000 and localhost:3000/library render the Library component, while localhost:3000/register renders the Register component.
When I run npm run build I get the build folder but when I enter the index.html page, it is blank.
This problem was introduced after I implemented the router. Previously the result of both npm start and npm run build were the same.
Here is the link to the same issue you are facing on the official create-react-app github issues
It is marked as closed there, you can also read that for more info.
You should serve the build folder for example like
npx serve -s build
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>
);
}
}
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.
Goto projects
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:
Use react-router-dom instead of react-router
Tell Express route all incoming traffic to index.html app.get("/*", (req, res) => res.sendFile(__dirname + '/public/index.html'));
Use <Switch> and <Route> components to setup the routes as described in the question. See code here.
Try to use exact directive:
<Route exact path="/" component={App} />
See API doc: https://reacttraining.com/react-router/web/api/Route/exact-bool
I'm working on a web application using react and have some problems with react-router. According to the tutorials I read I can access the router in version 3.0.0 with this.props.router and programmatically change the location with this.props.router.push('/home') for example.
In all those tutorials unfortunately, all the components are in the same file. However, my structure is to have every component in its own file.
The router is defined in the index.js file.
/src
/pages
Home.js
Landingpage.js
index.js
Above is the relevant part of my project structure. The following is the code of my index.js file
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import Landingpage from './pages/Landingpage'
import Home from './pages/Home'
import {
Router,
Route,
IndexRoute,
IndexLink,
Link,
browserHistory } from 'react-router';
import './index.css';
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Landingpage}/>
<Route path="home" component={Home}/>
</Route>
</Router>,
document.getElementById('root')
);
What I want is to access the above router instance in the files in my /pages directory. I tried several ways from the various tutorials, for example use withRouter(componentName) in the index.js file.
Thanks in advance