在 React 中构建客户数据库
有没有想过,如何获取互联网上关于人们的大量信息?比如,任何人的信息?
继续阅读本文,你会看到一个关于如何在服务器上保护 API 密钥的部分。如果你想了解更多关于如何保护 API 端点的信息,可以看看这篇文章
在本文中,我们将使用 ReactJS 在 Web 上构建一个客户端应用程序,并在前端集成Kelvin Data API。Kelvin Data 是一个 API 平台,可让您访问 Web 上的个人资料。
您可以使用他们的电子邮件地址、LinkedIn 个人资料(在这里,您必须提供此人的 LinkedIn URL。即https://linkedin.com/in/example-person)或他们的电话号码来搜索特定的人。
现在,让我们看看如何创建一个使用此 API 的应用程序。但是,在继续阅读本文之前,您应该具备以下基本知识:
- 反应,
- 使用 React 中的 Hooks 获取数据
- React 中的条件渲染
- JavaScript 中的字符串/模板文字,
- React 组件和 props
KelvinData 仪表板。
当您注册该平台时,您将可以访问个性化仪表板,您可以使用它来查看您的订阅、管理您的 API 密钥以及执行更多操作。
仪表板上还有一个搜索游乐场,您可以在其中测试 API 的功能。
您可以选择搜索任何人,包括姓名、电子邮件地址、领英个人资料或电话号码。本文将介绍如何仅使用全名搜索人员。
入门
就本文而言,我们将使用 NextJS 来引导我们的应用。这并不意味着create-react-app库无法使用。您可以使用任何您觉得方便的库。我们使用 NextJS 是因为它简单易用。您可以在此处阅读更多关于 NextJS 的信息。
首先安装此项目所需的依赖项。我们先创建一个 NextJS 应用。以下命令将自动完成此操作。
npx create-next-app [name-of-your-app]
我们将使用该"styled-components"库来设计我们的应用样式,并"axios"从 API 获取数据。本文不会过多介绍样式方面的内容。您可以在此处找到完整的应用样式。
让我们通过在终端中输入以下命令来获取上述依赖项。
npm install axios styled-components react-icons
下面我们来看看这个应用的文件结构。我们将重点介绍应用中需要的重要文件,以使其简洁明了。
|--pages
| |-- api
| | |-- users.js
| |-- _app.js
| |-- index.js
|--src
| |-- components
| | |-- Card.js
|__ .env.local
Next.js 应用程序中组件的概述
在本节中,我们将看到构成该项目架构的不同文件及其各自的功能。
该pages目录是应用程序所有路由发生的地方。这是 Nextjs 的一个开箱即用功能。它能帮你免去对独立路由进行硬编码的压力。
pages/api:api 目录使您能够在同一个代码库中为 nextjs 应用程序提供后端,而不是像通常那样为您的 REST 或 GraphQL API 创建单独的存储库并将它们部署在 Heroku 等后端托管平台上。
在该api目录中,每个文件都被视为一个 API 端点。如果您查看该文件夹,您会注意到其中api有一个名为的文件。user.js
该文件成为端点,这意味着可以使用文件路径作为基本 URL 执行 API 调用。
const getData = async() => {
axios.get("/api/users")
.then(response => response())
.then(response => console.log(response.data))
.catch(err => console.log(err)
}
pages/_app.js:是我们所有组件附加到 DOM 的地方。如果你查看组件结构,你会发现所有组件也都通过pagePropsprops传递Component。
它类似于index.js使用 Create-React-App 时的文件。唯一的区别是,你没有将你的应用挂接到名为“root”的 DOM 节点上。
React.render(document.getElementById("root), <App />)
index.js是 pages 文件夹中的默认路由。我们将在这里完成本项目的大部分工作。运行以下命令,它将启动一个开发服务器,并将 的内容index.js渲染到网页上。
npm run dev
-
Card.js:是保存我们从网页上的 API 获取的数据的组件 -
.env.local:是我们存储 API 密钥的地方,通过该密钥我们可以使用该 API。
编写服务器端 API 调用。
在上一节中,我们了解了将要交互的文件及其具体功能。在本节中,我们将了解如何使用 API。
我们在服务器端编写 API 调用的原因是为了保护我们的 API 密钥,而 Nextjs 已经使这项任务变得简单。
使用 Nextjs 中的 API 路由,我们可以执行 API 调用,而不必担心我们的 API 密钥在客户端被泄露。
在这种情况下,您可能想知道.env文件中的环境变量的本质是什么。
环境变量(也就是我们的 API 密钥)只能在development模式下使用。因此,我们可以执行类似 的操作process.env.api_key,并访问环境变量。
但是,当您将应用程序部署到 netlify 或 vercel 等平台时,模式会更改为production,这会使 nodejsprocess对象在客户端不可用。
现在你已经了解了为什么需要编写服务器端 API 调用。让我们立即开始吧。
// users.js
import axios from "axios"
export default async function users(req, res) {
const {
query: { firstName, lastName },
} = req;
const baseUrl = `https://api.kelvindata.com/rest/v1/search-v2? lastName=${lastName}&firstName=${firstName}&apiKey=${process.env.KEY}`;
const response = await axios.get(baseUrl);
res.status(200).json({
data: response.data,
});
}
在上面的代码片段中,我们创建了一个名为的异步函数。users它接受两个参数,req完整表示“请求”,res完整表示“响应”。
该req参数具有一些属性(或 Nextjs 文档所称的“中间件”),可以在我们使用 API 时访问,其中之一是req.query。
您会注意到,我们解构了query上面代码片段中的属性,因此我们可以将这些变量作为值传递给 API 端点的查询属性。请看下面。
您可以在此处req阅读有关该参数附带的内置中间件的更多信息。
const {
query: { firstName, lastName },
} = req;
基本 URL 将解构的查询属性作为值,并通过 nodejs 对象从文件apiKey中获取。.envprocess
解构的查询属性将作为请求,从表单组件(我们将在下一节中创建)的输入值发送到 API,一旦收到,我们就会得到与我们提出的请求相对应的响应。
const baseUrl = `https://api.kelvindata.com/rest/v1/searchv2? lastName=${lastName}&firstName=${firstName}&apiKey=${process.env.KEY}`;
该函数接下来要完成的处理是异步 API 调用的响应。下面的代码片段将我们正在使用axios库执行的 API 调用赋值给一个变量response。
在下一行中,res参数使用status向我们发送 JSON 响应的方法,然后我们可以将响应变量分配为data
您可以在此处阅读有关各种 HTTP 状态代码的更多信息
const response = await axios.get(baseUrl);
res.status(200).json({
data: response.data,
});
构建表单组件
在上一节中,我们了解了如何在服务器端编写 API 调用。在本节中,我们将使用该 API 调用来创建表单组件,该组件将输入字段中的名字和姓氏值发送到 API 查询参数。
为了避免文章篇幅过长,我们将尽量精简代码片段。我们先来看看index.js下面的内容。
import React from "react";
import styled from "styled-components";
import axios from "axios";
import Card from "../../components/Card";
const Wrapper = styled.section`
padding: 0 100px 0 100px;
height: 100%;
width: 100%;
// remaining style goes here
`;
const UserAPIComponent = () => {
const [userData, setUserData] = React.useState([]);
const [firstName, setFirstName] = React.useState("");
const [lastName, setLastName] = React.useState("");
const getuserData = async () => {
// api call goes here
};
const handleSubmit = (e) => {
e.preventDefault();
getuserData();
};
return (
<Wrapper>
<h3>Search for Anyone</h3>
<form onSubmit={handleSubmit}>
<label htmlFor="firstname">First name</label>
<input
type="text"
name="firstname"
value={firstName}
placeholder="First Name"
onChange={(e) => setFirstName(e.target.value)}
/>
<label htmlFor="lastname">Lastname</label>
<input
type="text"
name="lastname"
value={lastName}
placeholder="Lastname"
onChange={(e) => setLastName(e.target.value)}
/>
<div className="btn-container">
<Button>Search</Button>
</div>
</form>
<div className="results-container">
{userData ? <Card result={userData} />
: "loading..."}
</div>
</Wrapper>
);
};
export default UserAPIComponent;
由于这是一个从 API 端点接收数据的 React 组件,它应该具有自己的内部状态。下面的代码片段展示了我们如何使用 React Hooks 定义不同的状态变量。
const [userData, setUserData] = React.useState([]);
const [firstName, setFirstName] = React.useState("");
const [lastName, setLastName] = React.useState("");
firstName和变量lastName接收任何人在输入字段中输入的文本值。
状态变量userData帮助我们将从 API 调用中获得的响应存储在数组中,因此我们可以使用 JavaScriptmap()方法在网页上呈现响应。
请注意我们如何axios从 API 端点获取数据,以及基本 URL 不是典型的https://URL,而是我们之前进行服务器端 API 调用的文件的路径。
const getuserData = async () => {
axios.get(`/api/usersfirstName=${firstName}&lastName=${lastName}`, {
headers: {
Accept: "application/json",
"Access-Control-Allow-Origin": "*",
},
})
.then((response) => response)
.then((response) => {
setUserData(response.data.data);
})
.catch((err) => console.log(err));
};
我们在文件中重复几乎相同的过程user.js,但这次需要必要的获取标头并将状态变量分配给 API 查询参数。
在第二种.then()方法中,我们确保 API 调用的响应被视为数组,因此需要response.data.data。如果我们在 处停止setUserData(response.data),则每当我们尝试执行以下操作时,JavaScript 都会抛出类型错误:
{
userData.map((users, index) => {
return (
// some JSX
)
})
}
这是因为response.data它具有对象数据类型,并且该map()操作不适用于 JavaScript 对象,只适用于数组。
该handleSubmit处理程序确保在单击搜索按钮时,网页不会在每次 API 调用时重新加载。
const handleSubmit = (e) => {
e.preventDefault();
getuserData();
};
构建卡片组件
卡片组件是应用程序的展示组件。数据通过 React 中的 props 传递给它。
再次强调,为了简洁起见,我们不会详细讲解卡片组件的主要内容。我们先来看看下面修改后的结构。
import React from "react";
import { FiUser } from "react-icons/fi";
import styled from "styled-components";
const Wrapper = styled.div`
height: 56%;
width: 32%;
margin: 0 15px 30px 0;
background: #fff;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.05);
border-radius: 8px;
padding: 0 15px 0 15px;
`;
const Card = ({ result }) => {
return (
<>
{result.map((users, index) => {
return (
<Wrapper className="users-card" key={index}>
<p>
<span>
<FiUser />
</span>
{users.name.full !== null ?
users.name.full
: "no name data" }
</p>
<p>Title: {users.employments[0].title}</p>
<p>
Organization:
{
users.employments[0].organization.name !== null
? users.employments[0].organization.name
: "no employment info"}
</p>
</Wrapper>
);
})}
</>
);
};
export default Card;
该resultprop 被传递给Card组件,然后被 App 组件(在 中index.js)利用。
三元运算符检查 的有效性userData,如果是true,则Card渲染组件。如果不是 ,则loading…字符串显示在网页上。
<div className="results-container">
{userData ?
<Card result={userData} />
: "loading..."
}
</div>
您还会注意到我们如何使用下面“组织”段落中的三元运算符执行条件渲染。
如果没有任何与用户组织详细信息对应的数据,"no employment info"则显示该字符串。如果有,则显示用户的组织。
<p>
Organization:
{users.employments[0].organization.name !== null
? users.employments[0].organization.name
: "no employment info"}
</p>
结论
下面的视频展示了我们从本文开始一直在构建的最终成果。您可以随时检查浏览器的开发工具,转到“网络”选项卡,查看 API 密钥是否显示。
如果您想查看代码库,这里是它的链接。
该链接指向代码库中(本文的)具体文件。您可以在这里查看我的其他文章演示,也可以查看整个代码库。
如果您读到了这篇文章,非常感谢,请不要忘记分享。
文章来源:https://dev.to/seven/building-a-client-database-of-people-in-react-55oe
后端开发教程 - Java、Spring Boot 实战 - msg200.com

