package.json
that proxies non text/html
requests through to an alternative back end. You can use this feature to proxy to applications running elsewhere, but today we want to be able to run a server within the React project itself.create-react-app
package to do this? Instead, you can run:npm init react-app MyNewApp cd MyNewApp
npm init
takes an initializer name, prepends create-
to it and uses npx to install and run the command.npm start
devDependencies
of our React app as they aren't part of building the front end.Cmd/Ctrl + C
and use npm
to install Express and Body Parser:npm install express body-parser --save-dev
npm install node-env-run nodemon npm-run-all express-pino-logger pino-colada --save-dev
.env
in the project directory to store our environment variables. We don't need to add anything to it just yet, but it will be useful later for including any credentials we need for the server, like API keys.server
and a server/index.js
file. We'll create a small application that we can test with. Add the following code in server/index.js
:const express = require('express'); const bodyParser = require('body-parser'); const pino = require('express-pino-logger')(); const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(pino); app.get('/api/greeting', (req, res) => { const name = req.query.name || 'World'; res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify({ greeting: `Hello ${name}!` })); }); app.listen(3001, () => console.log('Express server is running on localhost:3001') );
package.json
and in the "scripts"
object add a new script to run the server using node-env-run
and nodemon
:"scripts": { // other scripts "server": "node-env-run server --exec nodemon | pino-colada" },
npm run server
name
to the URL and see what you get.package.json
."proxy"
key to package.json
. We've already set our server to run on port 3001, so point the proxy at localhost:3001."proxy": "http://localhost:3001"
npm-run-all
for this. Since we are going to be running two scripts at the same time we want to use the parallel mode. npm-run-all
gives us a handy shortcut for this with the run-p
command."scripts"
section in package.json
:"scripts": { // other scripts "server": "node-env-run server --exec nodemon", "dev": "run-p server start" },
npm run dev
and both the React application and the server will start up. However, we now can't load localhost:3000/api/greeting in the browser because the Create React App proxy will just respond with the base HTML.App
component that will use the /api/greeting
component to form a greeting and show it on the page. Add the following constructor and functions to the App component in src/App.js
:class App extends Component { constructor(props) { super(props); this.state = { name: '', greeting: '' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ name: event.target.value }); } handleSubmit(event) { event.preventDefault(); fetch(`/api/greeting?name=${encodeURIComponent(this.state.name)}`) .then(response => response.json()) .then(state => this.setState(state)); }
render
function:render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <form onSubmit={this.handleSubmit}> <label htmlFor="name">Enter your name: </label> <input id="name" type="text" value={this.state.name} onChange={this.handleChange} /> <button type="submit">Submit</button> </form> <p>{this.state.greeting}</p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); }
proxy
option and run an Express server alongside using tools like npm-run-all
.