React中POST HTTP请求的超详细教程

3,884 阅读8分钟

简介

在使用API的时候,我们经常想把数据发送到服务器上进行处理。例如,如果我们有一个待办事项的列表,并想添加到其中,也许是通过提交表单,我们使用POST HTTP请求来发送一个带有有效载荷的请求进行处理和潜在的持久化。

在这篇文章中,我们将学习如何使用两种常见的方法在React中执行POST HTTP请求:Fetch API和Axios。我们还将了解如何在功能型和基于类的组件中做到这一点。

使用Fetch API,用React发送POST HTTP请求就很容易了:

// Using Fetch API
fetch('/myserver.endpoint', {
  method: 'POST',
  body: JSON.stringify({
    // Add parameters here
  })
  headers: {
    'Content-type': 'application/json; charset=UTF-8',
  },
})
   .then((response) => response.json())
   .then((data) => {
      console.log(data);
      // Handle data
   })
   .catch((err) => {
      console.log(err.message);
   });

Axios为我们提供了一个优雅的替代品来发送HTTP POST请求:

// Using Axios - ensure you first install the package
axios.post('/myserver.endpoint', {
    // Add parameters here
  })
  .then((response) => {
    console.log(response.data);
      // Handle data
  })
  .catch((error) => {
    console.log(error);
  })

如果你想了解更多关于这些方法以及它们是如何工作的--请阅读本指南的其他部分!

什么是POST HTTP请求?

顾名思义,POST请求是用来发布数据到一个端点,然后端点通常会处理数据并将其保存在数据库中。这些数据可能来自一个表单,被保存在一个对象中,或以其他方式获得 - 但它通常被转换为JSON表示,供REST API使用。

通过Fetch API(内置)和Axios等库,用任何动词发送HTTP请求都变得简单。Fetch API是一个内置的浏览器方法,用于执行HTTP请求,而Axios是一个外部包,我们必须在使用前安装在我们的项目中。

在这两者之间的选择由你自己决定。Fetch API比较啰嗦,而且不能处理异步请求,但Axios是一个外部依赖。即便如此--许多人更喜欢用Axios而不是Fetch API工作。我们将介绍这两种方法。

这两种方法都有优点和缺点,但需要注意的是,它们可以处理标准的HTTP动词--POST,GET,PUT,PATCH,DELETE

注意:如前所述,我们将学习如何使用Fetch API和Axios方法在功能组件中执行POST 请求,然后在基于类的组件中使用JSON Placeholder Free Fake Posts REST API

在我们的实例中,我们将操作一个已经从模拟API中获取的帖子列表。我们将创建一个表单,接收一个新帖子的标题和正文,一旦提交,将发送一个POST请求到模拟服务器进行处理:

import { useState, useEffect } from 'react';

const App = () => {
   const [posts, setPosts] = useState([]);

   useEffect(() => {
      fetch('https://jsonplaceholder.typicode.com/posts?_limit=5')
         .then((res) => res.json())
         .then((data) => {
            console.log(data);
            setPosts(data);
         })
         .catch((err) => {
            console.log(err.message);
         });
   }, []);

   return (
      <>
         <div className="add-post-container">
            <form>
               <input type="text" className="form-control" />
               <textarea className="form-control" cols="10" rows="8"></textarea>
               <button type="submit">Add Post</button>
            </form>
         </div>
         <div className="posts-container">
            {posts.map((post) => {
               return (
                  <div className="post-card" key={post.id}>
                     <h2 className="post-title">{post.title}</h2>
                     <p className="post-body">{post.body}</p>
                     <div className="button">
                        <div className="delete-btn">Delete</div>
                     </div>
                  </div>
               );
            })}
         </div>
      </>
   );
};

export default App;

现在让我们让表单发挥作用,以便在表单提交后,我们可以向网站上的帖子列表添加数据。

如何在React的功能组件中执行POST HTTP请求

由于React中引入了钩子,我们现在可以在功能组件中执行HTTP请求。在此之前,功能组件只用于渲染UI。

当一个JavaScript函数(标准或ES6)返回一个React元素(JSX)时,就会创建一个功能组件。

我们现在不是像基于类的组件那样在构造方法中使用状态对象,而是使用React钩子,如useState() ,在将数据传入原始数据之前存储我们的数据。

如何在React的功能组件中使用Fetch API执行POST HTTP请求

因为Fetch API是一个内置的浏览器方法,返回一个Promise ,我们使用.then().catch() 方法来处理成功和失败。它还接受一个强制参数,即我们要向其中POST数据的资源/API的URL,以及一个表示HTTP请求的参数,在我们的例子中是POST

import { useState, useEffect } from 'react';

const App = () => {
   const [posts, setPosts] = useState([]);
   const [title, setTitle] = useState('');
   const [body, setBody] = useState('');
   
   // ... Fetch posts here
   
   // Handle psosts request
   const handleSubmit = (e) => {
      e.preventDefault();
      fetch('https://jsonplaceholder.typicode.com/posts', {
         method: 'POST',
         body: JSON.stringify({
            title: title,
            body: body,
            userId: Math.random().toString(36).slice(2),
         }),
         headers: {
            'Content-type': 'application/json; charset=UTF-8',
         },
      })
         .then((res) => res.json())
         .then((post) => {
            setPosts((posts) => [post, ...posts]);
            setTitle('');
            setBody('');
         })
         .catch((err) => {
            console.log(err.message);
         });
   };

   return (
      // ... JSX here
   );
};

export default App;

在上面的代码中,我们创建了一个方法,并将其链接到表单上,这样当表单的提交按钮被点击时就会触发。我们首先使用e.preventDefault() ,以防止提交表单时页面重新加载,这通常是你希望发生的,但对我们的演示来说效果并不好:

const handleSubmit = (e) => {
   e.preventDefault();
};

看一下fetch() 调用,我们把URL作为第一个强制参数,第二个参数接收请求方法(POST),body ,以及header

  • body - 包含了我们要发送至API终端的数据,我们必须对其进行字符串化处理,将其转化为基于文本的JSON表示。
  • header - 指定内容类型,在我们的例子中是 ,因为我们的有效载荷被表示为JSON字符串。application/json
const handleSubmit = (e) => {
   e.preventDefault();
   fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      body: JSON.stringify({
         title: title,
         body: body,
         userId: Math.random().toString(36).slice(2),
      }),
      headers: {
         'Content-type': 'application/json; charset=UTF-8',
      },
   })
};

最后,因为这个方法返回一个Promise ,我们将从中提取JSON内容(服务器的响应),更新posts 状态以包括新数据。

为了处理错误,我们还使用了.catch() 方法:

const handleSubmit = (e) => {
   e.preventDefault();
   fetch({...})
      .then((res) => res.json())
      .then((post) => {
         setPosts((posts) => [post, ...posts]);
         setTitle('');
         setBody('');
      })
      .catch((err) => {
         console.log(err.message);
      });
};

警告。通常情况下,你不会像我们这样在前端存储和处理数据,但由于我们使用的模拟API实际上不会保存和返回新的帖子--我们人为地把它添加到它确实从第一个GET请求返回的列表中。一旦帖子被存储在数据库中--我们就可以向后端发出另一个请求,以提供响应来显示给用户。这也是为什么表单提交的默认行为是重新加载页面--这将触发最初的fetch() GET请求,并自动显示新帖子和旧帖子。

如何使用Axios在React的功能组件中执行POST HTTP请求

我们在上一节中解释了如何使用Fetch API执行POST请求。现在,让我们修改handleSubmit() 方法,用Axios执行POST请求。

Axios是一个HTTP客户端库,它使用承诺,使其容易向REST端点发送异步HTTP请求。因为它是一个外部库,所以我们必须首先在我们的项目中安装它,在我们项目的目录中运行以下命令:

$ npm install axios

一旦我们成功安装了Axios,我们就可以继续执行我们的POST请求:

const handleSubmit = (e) => {
   e.preventDefault();
   axios
      .post('https://jsonplaceholder.typicode.com/posts', {
         title: title,
         body: body,
      })
      .then((res) => {
         setPosts((posts) => [res.data, ...posts]);
         setTitle('');
         setBody('');
      })
      .catch((err) => {
         console.log(err.message);
      });
};

看看上面的代码,它比Fetch API要简单得多,需要的语法也少得多,因为我们不再需要转换为JSON,处理头信息,甚至对数据进行字符串化处理。这些模板被Axios抽象出来了。

如何在React的类组件中执行POST HTTP请求

类组件中的POST请求与功能组件中的处理方式不同,因为我们不再使用React钩子,而是使用state 对象:

类组件是一个ES6类,返回JSX,需要React扩展。

如何在React的类组件中使用Fetch API执行POST HTTP请求

该请求与功能组件的请求非常相似。我们唯一会发现一些不同的地方是在state 中存储数据和使用state 值时,因为我们不再使用useState() 钩:

import React, { Component } from 'react';

class App extends Component {

   constructor(props) {
      super(props);
      this.state = {
         posts: [],
      };
   }
   
   // ...   

   handleSubmit = (e) => {
      e.preventDefault();
      fetch('https://jsonplaceholder.typicode.com/posts', {
         method: 'POST',
         body: JSON.stringify({
            title: this.state.title,
            body: this.state.body,
            userId: Math.random().toString(36).slice(2),
         }),
         headers: {
            'Content-type': 'application/json; charset=UTF-8',
         },
      })
         .then((response) => response.json())
         .then((data) => {
            this.setState({ posts: [data, ...this.state.posts] });
            this.setState({ title: '' });
            this.setState({ body: '' });
         })
         .catch((err) => {
            console.log(err.message);
         });
   };

   render() {
      const { posts, title, body } = this.state;
      return (
         // ... JSX here
      );
   }
}

export default App;

这一次,我们不再用const 关键字来声明方法。相反,用this 作为前缀。当表单的提交按钮被点击时,这个方法将被触发。既然是表单,我们先用e.preventDefault() ,以防止表单提交时页面重新加载:

handleSubmit = (e) => {
   e.preventDefault();
};

就像我们之前学到的,Fetch API接收两个参数。一个是URL,而第二个则包含请求方法(POST )、body 等选项,这是我们要发布的信息(必须是字符串),然后是headers

handleSubmit = (e) => {
   e.preventDefault();
   fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      body: JSON.stringify({
         title: this.state.title,
         body: this.state.body,
         userId: Math.random().toString(36).slice(2),
      }),
      headers: {
         'Content-type': 'application/json; charset=UTF-8',
      },
   })
};

知道这是一个承诺,我们现在可以附加.then() 方法来处理成功,以及.catch() 方法来处理HTTP请求中出现错误或失败的情况。

如何使用Axios在React的类组件中执行POST HTTP请求

我们已经看到如何在基于类的组件中执行POST HTTP请求。这与Axios非常相似,因为我们所要做的就是安装Axios,然后替换handleSubmit() 方法,所以我们现在使用Axios而不是Fetch API:

handleSubmit = (e) => {
   e.preventDefault();
   axios
      .post('https://jsonplaceholder.typicode.com/posts', {
         title: this.state.title,
         body: this.state.body,
         userId: 1,
      })
      .then((response) => {
         this.setState({ posts: [response.data, ...this.state.posts] });
         this.setState({ title: '' });
         this.setState({ body: '' });
      })
      .catch((error) => console.log(error));
};

结论

在本指南中,我们学习了如何使用React中的两个主要方法来执行POST HTTP请求。我们还看到了如何在功能型和基于类的组件中完成这些工作,所以无论我们的项目中使用什么,这篇文章都可以为我们服务。