简介
在使用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请求。我们还看到了如何在功能型和基于类的组件中完成这些工作,所以无论我们的项目中使用什么,这篇文章都可以为我们服务。