简介

React 是一种流行的前端框架,开发人员使用它来创建应用程序。如果您想构建真实世界的应用程序,您将需要在某个时候将 API 集成到您的 React 应用程序中。每个想要使用 React 构建现代、真实的 Web 应用程序的开发人员都必须了解如何使用 API 将数据提取到 React 应用程序中。

在本初学者指南中,我们将学习如何在 React 中使用 RESTful API,包括获取、删除和添加数据。我们还将讨论使用 RESTful API 的两种主要方式以及如何将它们与 React 挂钩一起使用。

什么是 REST API?

如果您曾经花时间进行编程或研究编程,那么您几乎肯定会遇到“API”一词。 API代表应用程序编程接口,它是一种允许不同应用程序以编程方式相互通信并实时返回响应的媒介。

Roy Fielding 在 2000 年将 REST 定义为一种架构风格和方法论,通常用于开发互联网服务,例如分布式超媒体系统。它是代表“REpresentational State Transfer”的首字母缩写词。

当通过 REST API 发出请求时,它会将资源当前状态的表示发送给请求者或端点。这种状态表示可以采用 JSON(JavaScript Object Notation)、XML 或 HTML 的形式。 JSON 是使用最广泛的文件格式,因为它与语言无关,可以被人和机器读取。

例如:

[
   {
      "userId": 1,
      "id": 1,
      "title": "sunt excepturi",
      "body": "quia et suscipit\nsuscipit recusandae consequuntur "
   },
   {
      "userId": 1,
      "id": 2,
      "title": "qui est esse",
      "body": "est rerum tempore vitae\nsequi sint nihil"
   }
]

进入全屏模式 退出全屏模式

在 React 中使用 REST API

在 React 应用程序中使用 REST API 可以通过多种方式完成,但在本指南中,我们将介绍两种最流行的方法:Axios(基于 Promise 的 HTTP 客户端)和 Fetch API(浏览器内置网络 API)。

注意: 要完全理解本指南,您应该熟悉 JavaScript、React 和 React 钩子,因为它们是本指南的核心。

在我们了解如何使用 API 之前,重要的是要了解在 React 中使用 API 与在 JavaScript 中的使用方式非常不同,因为这些请求现在是在 React 组件中完成的。在我们的例子中,我们将使用函数式组件,这需要使用两个主要的 React Hooks:

  • useEffect Hook: 在 React 中,我们在useEffect()挂钩中执行 API 请求,以便在应用程序挂载或达到特定状态后立即呈现。这是将使用的一般语法:
useEffect(() => {
    // data fetching here
}, []);

进入全屏模式 退出全屏模式

  • useState Hook: 当我们请求数据时,我们必须准备一个状态,当数据返回时将被存储在这个状态。我们可以将其保存在 Redux 等状态管理工具或上下文对象中。为简单起见,我们将返回的数据存储在 React 本地状态中。
const [posts, setPosts] = useState([]);

进入全屏模式 退出全屏模式

现在让我们深入了解本指南的内容,我们将在其中学习如何使用JSONPlaceholder Post API获取、添加和删除数据。这些知识适用于任何类型的 API,因为本指南适用于初学者。

使用 Fetch API 使用 API

Fetch API 是一种 JavaScript 内置方法,用于从服务器或 API 端点检索资源。这是内置的,不需要安装任何依赖项或包。

fetch()方法需要一个强制参数,它是您要获取的资源的路径或 URL,然后返回一个 Promise,以便您可以使用then()catch()方法处理成功或失败。

一个基本的获取请求编写起来非常简单,如下所示:我们只是从一个以 JSON 格式返回数据的 URL 获取数据,然后将其记录到控制台:

fetch('https://jsonplaceholder.typicode.com/posts?_limit=10')
   .then(response => response.json())
   .then(data => console.log(data));

进入全屏模式 退出全屏模式

注意: 默认响应通常是常规的 HTTP 响应而不是实际的 JSON,但我们可以使用响应的 json() 方法将输出作为 JSON 对象获取。

使用 Fetch API 在 React 中执行 GET 请求

HTTP GET 方法可用于从端点请求数据;如前所述,Fetch API 接受一个强制参数,这是正确的;它还接受一个可选参数,这是可选的,尤其是在使用 GET 方法时,这是默认的;但是,对于 POST 和 DELETE 等其他方法,需要将该方法附加到选项数组:

fetch(url, {
    method: "GET" // default, so we can ignore
})

进入全屏模式 退出全屏模式

到目前为止,我们已经了解了事情是如何工作的,所以让我们把我们学到的所有东西放在一起,并执行一个 get 请求来从我们的 API 中获取数据。如前所述,我们将使用免费在线 API JSONPlaceholder将帖子列表获取到我们的应用程序中:

import React, { useState, useEffect } from 'react';

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

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

进入全屏模式 退出全屏模式

我们在前面的代码中创建了一个状态来存储我们将从 API 检索到的数据,以便我们稍后可以在我们的应用程序中使用它,我们还将默认值设置为一个空数组。

const [posts, setPosts] = useState([]);

进入全屏模式 退出全屏模式

然后主要操作发生在 useEffect 状态,以便在应用程序加载后立即获取数据/帖子。获取请求产生一个承诺,我们可以接受或拒绝:

useEffect(() => {
   fetch('https://jsonplaceholder.typicode.com/posts?_limit=10').then(
      (response) => console.log(response)
   );
}, []);

进入全屏模式 退出全屏模式

此响应包含大量数据,例如状态代码、文本和其他稍后处理错误所需的信息。到目前为止,我们已经使用.then()处理了一个解析,但是它返回了一个响应对象,这不是我们想要的,所以我们需要使用json()方法将响应对象解析为 JSON 格式,这也为我们返回了一个承诺使用第二个.then()获取实际数据。

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

进入全屏模式 退出全屏模式

如果我们查看控制台,我们会看到我们从 API 中检索了 10 个帖子,我们也将它们设置为我们之前指定的状态。这并不完整,因为我们只处理了 promise 的 resolve 而不是 promise 的拒绝,它使用.catch()方法处理:

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

进入全屏模式 退出全屏模式

到目前为止,我们已经了解了如何执行GET请求,这可以通过遍历我们的数组轻松地在我们的应用程序中使用:

const App = () => {
// ...

   return (
   <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;

进入全屏模式 退出全屏模式

使用 Fetch API 在 React 中执行 POST 请求

HTTPPOST方法可用于从端点发送数据;它的工作方式类似于GET请求,主要区别在于必须将方法和两个附加参数添加到可选对象:

const addPosts = async (title, body) => {
await 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((response) => response.json())
.then((data) => {
   setPosts((posts) => [data, ...posts]);
   setTitle('');
   setBody('');
})
.catch((err) => {
   console.log(err.message);
});
};

进入全屏模式 退出全屏模式

会显得奇怪的主要参数是正文和标题。主体包含我们想要传递给 API 的数据,我们必须首先对其进行字符串化,因为我们正在将数据发送到 Web 服务器,并且标头告诉数据的类型,这在使用 REST API 时总是相同的。我们还将状态设置为保存新数据并将剩余数据分配到数组中。

查看我们创建的addPost()方法,它期望这些数据来自表单或其他任何东西;在我们的例子中,我创建了一个表单,通过状态获取表单数据,然后在提交表单时将其添加到方法中:

import React, { useState, useEffect } from 'react';
const App = () => {
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
// ...
const addPosts = async (title, body) => {
   await 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((response) => response.json())
      .then((data) => {
         setPosts((posts) => [data, ...posts]);
         setTitle('');
         setBody('');
      })
      .catch((err) => {
         console.log(err.message);
      });
};

const handleSubmit = (e) => {
   e.preventDefault();
   addPosts(title, body);
};    

return (
   <div className="app">
      <div className="add-post-container">
         <form onSubmit={handleSubmit}>
            <input type="text" className="form-control" value={title}
               onChange={(e) => setTitle(e.target.value)}
            />
            <textarea name="" className="form-control" id="" cols="10" rows="8" 
               value={body} onChange={(e) => setBody(e.target.value)} 
            ></textarea>
            <button type="submit">Add Post</button>
         </form>
      </div>
      {/* ... */}
   </div>
);
};

export default App;

进入全屏模式 退出全屏模式

使用 Fetch API 在 React 中执行 DELETE 请求

HTTPDELETE方法可用于从端点删除数据;它的工作原理类似于GET请求,主要区别在于添加了方法:

const deletePost = async (id) => {
await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
   method: 'DELETE',
}).then((response) => {
   if (response.status === 200) {
      setPosts(
         posts.filter((post) => {
            return post.id !== id;
         })
      );
   } else {
      return;
   }
});
};

进入全屏模式 退出全屏模式

这在单击按钮时触发,我们得到单击按钮的特定帖子的id,然后我们从整个重新调整的数据中删除该数据。这将从 API 中删除,但不会立即从 UI 中删除,这就是我们添加过滤器来删除数据的原因。对于循环中的每个项目,您的删除按钮将如下所示:

const App = () => {
// ...

   return (
   <div className="posts-container">
      {posts.map((post) => {
         return (
            <div className="post-card" key={post.id}>
               {/* ... */}
               <div className="button">
                  <div className="delete-btn" onClick={() => deletePost(post.id)}>
                     Delete
                  </div>
               </div>    
            </div>
         );
      })}
   </div>
   );
};

export default App;

进入全屏模式 退出全屏模式

在 Fetch API 中使用 Async/Await

到目前为止,我们已经看到了如何使用 promise 语法正常地发出 fetch 请求,由于.然后是链接。我们可以通过使用 Async/await 来避免 .then 链接,并编写更具可读性的代码。

要使用 async/await,首先在函数中调用async,然后在发出请求并期待响应时,在函数前面添加await语法等待直到 promise 得到结果。

当我们使用 async/await 时,我们所有的 Fetch 请求将如下所示:

import React, { useState, useEffect } from 'react';

const App = () => {
   const [title, setTitle] = useState('');
   const [body, setBody] = useState('');
   const [posts, setPosts] = useState([]);

   // GET with fetch API
   useEffect(() => {
      const fetchPost = async () => {
         const response = await fetch(
            'https://jsonplaceholder.typicode.com/posts?_limit=10'
         );
         const data = await response.json();
         console.log(data);
         setPosts(data);
      };
      fetchPost();
   }, []);

   // Delete with fetchAPI
   const deletePost = async (id) => {
      let response = await fetch(
         `https://jsonplaceholder.typicode.com/posts/${id}`,
         {
            method: 'DELETE',
         }
      );
      if (response.status === 200) {
         setPosts(
            posts.filter((post) => {
               return post.id !== id;
            })
         );
      } else {
         return;
      }
   };

   // Post with fetchAPI
   const addPosts = async (title, body) => {
      let response = await 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',
         },
      });
      let data = await response.json();
      setPosts((posts) => [data, ...posts]);
      setTitle('');
      setBody('');
   };

   const handleSubmit = (e) => {
      e.preventDefault();
      addPosts(title, body);
   };

   return (
      // ...
   );
};

export default App;

进入全屏模式 退出全屏模式

处理错误

在本节中,我们将了解如何以传统方式和使用 async/await 来处理错误。我们可以使用响应数据来处理 Fetch API 中的错误,也可以在使用 async/await 时使用 try/catch 语句。让我们看看我们如何在 Fetch API 中正常执行此操作:

const fetchPost = () => {
fetch('https://jsonplaceholder.typicode.com/posts?_limit=10')
   .then((response) => {
      if (!response.ok) {
         throw Error(response.statusText);
      }
      return response.json();
   })
   .then((data) => {
      console.log(data);
      setPosts(data);
   })
   .catch((err) => {
      console.log(err.message);
   });
};

进入全屏模式 退出全屏模式

您可以在此处阅读有关 Fetch API 错误的更多信息。

对于 async/await,我们可以像这样使用trycatch:

const fetchPost = async () => {
   try {
      const response = await fetch(
         'https://jsonplaceholder.typicode.com/posts?_limit=10'
      );
      const data = await response.json();
      setPosts(data);
   } catch (error) {
      console.log(error);
   }
};

进入全屏模式 退出全屏模式

使用 Axios 消费 API

Axios 是一个基于 Promise 的 HTTP 客户端库,它使得向 REST 端点发送异步 HTTP 请求变得简单。在我们的例子中,这个端点是 JSONPlaceholder Posts API,我们将向其发出GETPOSTDELETE个请求。

安装和配置Axios实例

Axios 与 Fetch API 不同,它不是内置的,因此我们需要将其合并到我们的项目中才能使用它。我们可以通过运行以下命令将 Axios 添加到我们的项目中:

npm install axios

进入全屏模式 退出全屏模式

一旦成功安装,我们就可以继续创建一个实例,这是可选的,但建议这样做,因为它可以避免我们不必要的重复。要创建实例,我们使用.create()方法,该方法可用于指定 URL 和可能的标头等信息:

import axios from "axios";

const client = axios.create({
   baseURL: "https://jsonplaceholder.typicode.com/posts" 
});

进入全屏模式 退出全屏模式

使用 Axios 在 React 中执行 GET 请求

我们将使用我们之前声明的实例,我们要做的就是设置参数(如果有),并默认以 json 格式获取响应。与 Fetch API 方法不同,声明方法不需要任何选项;我们只需将方法附加到实例并查询它。

useEffect(() => {
   client.get('?_limit=10').then((response) => {
      setPosts(response.data);
   });
}, []);

进入全屏模式 退出全屏模式

使用 Axios 在 React 中执行 POST 请求

如前所述,POST方法可用于向端点发送数据;它的功能类似于GET请求,主要区别在于要求包含方法和保存我们发送的数据的选项:

const addPosts = (title, body) => {
   client
      .post('', {
         title: title,
         body: body,
      })
      .then((response) => {
         setPosts((posts) => [response.data, ...posts]);
      });
};

进入全屏模式 退出全屏模式

使用 Axios 在 React 中执行 DELETE 请求

我们可以使用 delete 方法执行删除请求,它将获取id并将其从 API 中删除,我们还将使用 filter 方法将其从 UI 中删除,就像我们使用 Fetch API 方法所做的那样:

const deletePost = (id) => {
   client.delete(`${id}`);
   setPosts(
      posts.filter((post) => {
         return post.id !== id;
      })
   );
};

进入全屏模式 退出全屏模式

在 Axios 中使用 Async/Await

到目前为止,我们已经了解了如何使用 promise 语法发出 Axios 请求,但现在让我们看看如何使用 async/await 来编写更少的代码并避免.then()链接。

当我们使用 async/await 时,我们所有的 Axios 请求将如下所示:

import React, { useState, useEffect } from 'react';

const App = () => {
   const [title, setTitle] = useState('');
   const [body, setBody] = useState('');
   const [posts, setPosts] = useState([]);

   // GET with Axios
   useEffect(() => {
      const fetchPost = async () => {
         let response = await client.get('?_limit=10');
         setPosts(response.data);
      };
      fetchPost();
   }, []);

   // Delete with Axios
   const deletePost = async (id) => {
      await client.delete(`${id}`);
      setPosts(
         posts.filter((post) => {
            return post.id !== id;
         })
      );
   };

   // Post with Axios
   const addPosts = async (title, body) => {
      let response = await client.post('', {
         title: title,
         body: body,
      });
      setPosts((posts) => [response.data, ...posts]);
   };

   const handleSubmit = (e) => {
      e.preventDefault();
      addPosts(title, body);
   };

   return (
      // ...
   );
};

export default App;

进入全屏模式 退出全屏模式

处理错误

对于基于 promise 的 axios 请求,我们可以使用.then()和 .catch () 方法,但对于 async/await,我们可以使用try...catch块。这与 Fetch API 的实现方式非常相似,try...catch块将如下所示:

const fetchPost = async () => {
   try {
      let response = await client.get('?_limit=10');
      setPosts(response.data);
   } catch (error) {
      console.log(error);
   }
};

进入全屏模式 退出全屏模式

您可以在此处阅读有关使用 Axios处理错误的更多信息。

Fetch API vs Axios

您可能已经注意到一些差异,但我们也很高兴注意到一些差异。这些区别将帮助您决定对特定项目使用哪种方法。这些区别包括:

爱讯

拿来

Axios 是一个独立的第三方包,安装简单。

Fetch 内置于大多数现代浏览器中; 不需要安装

Axios 使用 data 属性。

Fetch 使用 body 属性。

Axios 数据包含对象

Fetch 的主体必须是字符串化的

当状态为 200 且 statusText 为 'ON' 时,Axios 请求被接受。

response 对象包含 ok 属性时,获取请求是可以的。

Axios 执行 JSON 数据的自动转换

在处理 JSON 数据时,Fetch 是一个两步过程——首先,发出实际请求;其次,在响应上调用 .json() 方法。

Axios 允许取消请求和请求超时

获取没有。

Axios 具有对下载进度的内置支持

Fetch 不支持上传进度。

Axios 具有广泛的浏览器支持

当状态为 200 且 statusText 为“OK”时,Axios 请求被接受。 Fetch 仅与 Chrome 42+、Firefox 39+、Edge 14+ 和 Safari 10.1+ 兼容。 (这称为向后兼容性)。

结论

在本指南中,我们学习了如何使用 Fetch API 或 Axios 在 react 中使用 REST API。这将帮助您开始使用 React 中的 API 消费,并且从那里您将能够执行更多独特的数据消费和 API 操作。

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐