如何使create-react-app与Node Back-end API一起使用

This is a very common question among newer React developers, and one question I had when I was starting out with React and Node.js. In this short example I will show you how to make create-react-app work with Node.js and Express Back-end.

这在新的React开发人员中是一个非常常见的问题,也是我刚开始使用React和Node.js时遇到的一个问题。 在这个简短的示例中,我将向您展示如何使Node.js和Express Back-end可以使用create-react-app

创建React应用 (create-react-app)

Create a project using create-react-app.

使用create-react-app创建一个项目。

npx create-react-app example-create-react-app-express

Create a /client directory under example-create-react-app-express directory and move all the React boilerplate code created by create-react-app to this new client directory.

example-create-react-app-express目录下创建一个/client目录,并将所有由create-react-app的React样板代码移动到该新客户端目录。

cd example-create-react-app-expressmkdir client
节点快速服务器 (The Node Express Server)

Create a package.json file inside the root directory (example-create-react-app-express) and copy the following contents:

在根目录( example-create-react-app-express )内创建一个package.json文件,并复制以下内容:

{
  "name": "example-create-react-app-express",
  "version": "1.0.0",
  "scripts": {
    "client": "cd client && yarn start",
    "server": "nodemon server.js",
    "dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
  },
  "dependencies": {
    "body-parser": "^1.18.3",
    "express": "^4.16.4"
  },
  "devDependencies": {
    "concurrently": "^4.0.1"
  }
}

Notice I am using concurrently to run the React app and Server at the same time. The –kill-others-on-fail flag will kill other processes if one exits with a non zero status code.

注意我正在concurrently使用来concurrently运行React应用程序和Server。 如果一个以非零状态码退出,则–kill-others-on-fail标志将杀死其他进程。

Install nodemon globally and the server dependencies:

全局安装nodemon和服务器依赖项:

npm i nodemon -g
yarn

Create a server.js file and copy the following contents:

创建一个server.js文件并复制以下内容:

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get('/api/hello', (req, res) => {
  res.send({ express: 'Hello From Express' });
});

app.post('/api/world', (req, res) => {
  console.log(req.body);
  res.send(
    `I received your POST request. This is what you sent me: ${req.body.post}`,
  );
});

app.listen(port, () => console.log(`Listening on port ${port}`));

This is a simple Express server that will run on port 5000 and have two API routes: GET - /api/hello, and POST -/api/world.

这是一个简单的Express服务器,将在端口5000上运行,并具有两个API路由: GET /api/helloPOST /api/world

At this point you can run the Express server with the following command (still inside the root directory):

此时,您可以使用以下命令运行Express服务器(仍在根目录中):

node server.js

Now navigate to http://localhost:5000/api/hello, and you will get the following:

现在导航到http://localhost:5000/api/hello ,您将获得以下信息:

We will test the POST route once we build the React app.

构建React应用后,我们将测试POST路由。

React App (The React App)

Now switch over to the client directory where our React app lives.

现在切换到我们的React应用程序所在的client目录。

Add the following line to the package.json file created by create-react-app.

package.json下行添加到create-react-apppackage.json文件中。

"proxy": "http://localhost:5000/"

The key to using an Express back-end server with a project created with create-react-app is to use a proxy. This tells the Web-pack development server to proxy our API requests to our API server, given that our Express server is running on localhost:5000.

将Express后端服务器与通过create-react-app的项目一起使用的关键是使用代理。 假设我们的Express服务器在localhost:5000上运行,这将告诉Web-pack开发服务器将我们的API请求代理到我们的API服务器。

Now modify ./client/src/App.js to call our Express API Back-end, changes are in bold.

现在修改./client/src/App.js来调用我们的Express API后端,更改以粗体显示。

import React, { Component } from 'react';

import logo from './logo.svg';

import './App.css';

class App extends Component {
  state = {
    response: '',
    post: '',
    responseToPost: '',
  };
  
  componentDidMount() {
    this.callApi()
      .then(res => this.setState({ response: res.express }))
      .catch(err => console.log(err));
  }
  
  callApi = async () => {
    const response = await fetch('/api/hello');
    const body = await response.json();
    if (response.status !== 200) throw Error(body.message);
    
    return body;
  };
  
  handleSubmit = async e => {
    e.preventDefault();
    const response = await fetch('/api/world', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ post: this.state.post }),
    });
    const body = await response.text();
    
    this.setState({ responseToPost: body });
  };
  
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>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
        <p>{this.state.response}</p>
        <form onSubmit={this.handleSubmit}>
          <p>
            <strong>Post to Server:</strong>
          </p>
          <input
            type="text"
            value={this.state.post}
            onChange={e => this.setState({ post: e.target.value })}
          />
          <button type="submit">Submit</button>
        </form>
        <p>{this.state.responseToPost}</p>
      </div>
    );
  }
}

export default App;

We create callApi method to interact with our GET Express API route, then we call this method in componentDidMount and finally set the state to the API response, which will be Hello From Express.

我们创建callApi方法来与GET Express API路由进行交互,然后在componentDidMount调用此方法,最后将状态设置为API响应,即“ Hello From Express”

Notice we didn’t use a fully qualified URL http://localhost:5000/api/hello to call our API, even though our React app runs on a different port (3000). This is because of the proxy line we added to the package.json file earlier.

请注意,即使我们的React应用程序在其他端口(3000)上运行,我们也没有使用完全限定的URL http://localhost:5000/api/hello来调用我们的API。 这是因为proxy 我们之前添加到package.json文件中的行。

We have a form with a single input. When submitted calls handleSubmit, which in turn calls our POST Express API route then saves the response to state and displays a message to the user: I received your POST request. This is what you sent me: [message from input].

我们有一个带有单个输入的表单。 提交时,调用handleSubmit ,然后依次调用我们的POST Express API路由,然后将响应保存到状态并向用户显示一条消息: 我收到了您的POST请求。 这是您发送给我的:[来自输入的消息]

Now open ./client/src/App.css and modify .App-header class as follows (changes in bold)

现在打开./client/src/App.css并按如下所示修改.App-header类(更改为粗体)

.App-header {
...
  min-height: 50%;
...
  padding-bottom: 10px;
}

运行应用 (Running the App)

If you still have the server running, go ahead and stop it by pressing Ctrl+C in your terminal.

如果您仍在运行服务器,请在终端中按Ctrl + C停止它。

From the project root directory run the following:

从项目根目录运行以下命令:

yarn dev

This will launch the React app and run the server at the same time.

这将启动React应用程序并同时运行服务器。

Now navigate to http://localhost:3000 and you will hit the React app displaying the message coming from our GET Express route. Nice ?!

现在导航到http://localhost:3000 ,您将点击React应用,显示来自我们GET Express路由的消息。 很好?!

Now, type something in the input field and submit the form, you will see the response from the POST Express route displayed right below the input field.

现在,在输入字段中输入内容并提交表单,您将看到输入字段正下方显示的POST Express路由的响应。

Finally take a look at at your terminal, you will see the message we sent from the client, that is because we call console.log on the request body in the POST Express route.

最后看看您的终端,您将看到我们从客户端发送的消息,这是因为我们在POST Express路由的请求正文上调用console.log

生产部署到Heroku (Production Deployment to Heroku)

Open server.js and replace with the following contents:

打开server.js并替换为以下内容:

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');

const app = express();
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// API calls
app.get('/api/hello', (req, res) => {
  res.send({ express: 'Hello From Express' });
});

app.post('/api/world', (req, res) => {
  console.log(req.body);
  res.send(
    `I received your POST request. This is what you sent me: ${req.body.post}`,
  );
});

if (process.env.NODE_ENV === 'production') {
  // Serve any static files
  app.use(express.static(path.join(__dirname, 'client/build')));
    
  // Handle React routing, return all requests to React app
  app.get('*', function(req, res) {
    res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
  });
}

app.listen(port, () => console.log(`Listening on port ${port}`));

Open ./package.json and add the following to the scripts entry

打开./package.json并将以下内容添加到scripts条目中

"start": "node server.js",
"heroku-postbuild": "cd client && npm install && npm install --only=dev --no-shrinkwrap && npm run build"

Heroku will run the start script by default and this will serve our app. Then we want to instruct Heroku to build our client app, we do so with heroku-postbuild script.

Heroku默认会运行start脚本,这将为我们的应用程序提供服务。 然后,我们要指示Heroku构建我们的客户端应用程序,我们使用heroku-postbuild脚本来实现。

Now, head over to Heroku and log in (or open an account if you don’t have one).

现在,转到Heroku并登录(如果没有,请开设一个帐户)。

Create a new app and give it a name

创建一个新应用并命名

Click on the Deploy tab and follow the deploy instructions (which I think they are pretty self-explanatory, no point on replicating them here ?)

单击“ 部署”选项卡,然后按照部署说明进行操作(我认为它们很不言自明,没有必要在此处复制它们吗?)

And that is it, you can open your app by clicking on the Open app button at the top right corner within the Heroku dashboard for your app.

就是这样,您可以通过单击Heroku仪表板右上角的“ 打开应用程序”按钮来打开应用程序。

Visit the deployed app for this tutorial: https://cra-express.herokuapp.com/

请访问已部署的应用程序以获取本教程: https : //cra-express.herokuapp.com/

其他部署选项 (Other Deployment Options)

I write about other deployments options here:

我在这里写有关其他部署选项的信息:

项目结构 (Project Structure)

This will be the final project structure.

这将是最终的项目结构。

Get the full code on the GitHub repository.

GitHub存储库上获取完整代码。

Thank you for reading and I hope you enjoyed it. Any question, suggestions let me know in the comments below!

感谢您的阅读,希望您喜欢它。 如有任何疑问,建议请在下面的评论中告诉我!

You can follow me on Twitter, GitHub, Medium, LinkedIn or all of them.

您可以在TwitterGitHubMediumLinkedIn或所有它们上关注我。

This post was originally posted on my personal blog website.

该帖子最初发布在我的个人博客网站上



Update 8/25/19: I have been building a prayer web app called "My Quiet Time - A Prayer Journal". If you would like to stay in the loop please sign up through the following link: http://b.link/mqt  

19年8月25日更新:我一直在构建一个祷告网络应用程序,名为“ 我的安静时间-祷告日记 ”。 如果您想停留在循环中,请通过以下链接进行注册: http : //b.link/mqt

The app will be released before the end of the year, I have big plans for this app. To see some mockup screenshots follow the following link: http://pc.cd/Lpy7

该应用程序将在今年年底之前发布,我对此应用程序有很大的计划。 要查看一些模型截图,请点击以下链接: http : //pc.cd/Lpy7

My DMs on Twitter are open if you have any questions regarding the app 😄

如果您对应用程序有任何疑问,我在Twitter上的 DM处于打开状态😄

翻译自: https://www.freecodecamp.org/news/how-to-make-create-react-app-work-with-a-node-backend-api-7c5c48acb1b0/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值