当你向API发送一个GET请求时,你会从服务器上得到响应数据。但有时管理这些数据会成为一个问题。
在这篇博文中,我将告诉你如何在React中创建一个搜索过滤器。它将使用功能组件和React钩子在数据中搜索一个特定术语。
如何向API发出一个GET请求
首先,让我们向API发出一个GET请求,它将从服务器上获取一些数据。你可以使用任何你想要的服务器来获取数据,但在本文中我将使用{JSON}占位符来获取用户列表。
在这个例子中,我们有一些卡片,显示不同用户的名字和电子邮件。我们也有一个搜索输入框,我们将用它来搜索一个特定的用户:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Card, Input } from 'semantic-ui-react'
export default function Posts() {
const [APIData, setAPIData] = useState([])
useEffect(() => {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then((response) => {
setAPIData(response.data);
})
}, [])
return (
<div style={{ padding: 20 }}>
<Input icon='search'
placeholder='Search...'
/>
<Card.Group itemsPerRow={3} style={{ marginTop: 20 }}>
{APIData.map((item) => {
return (
<Card>
<Card.Content>
<Card.Header>{item.name}</Card.Header>
<Card.Description>
{item.email}
</Card.Description>
</Card.Content>
</Card>
)
})}
</Card.Group>
</div>
)
}
从JSON占位符中获取用户列表

获取用户列表和顶部的搜索输入框
如果你不知道如何在React中处理GET API调用,请关注我在React CRUD操作上的博客或我在React CRUD操作上的视频,在那里我告诉你如何在React中处理API调用。
如何从搜索输入框中获得搜索输入
现在,让我们从搜索输入框中获取我们的搜索查询。
为搜索输入创建一个状态:
const [searchInput, setSearchInput] = useState('');
创建搜索输入的状态
这里,searchInput 是一个字符串,我们将使用setSearchInput 来设置搜索输入。
现在,我们将创建一个函数来处理我们的搜索功能:
const searchItems = () => {
}
创建一个函数来处理我们的搜索功能
并通过onChange 事件将此函数与搜索输入绑定:
<Input icon='search'
placeholder='Search...'
onChange={() => searchItems()}
/>
将searchItems函数绑定到输入字段上
因此,每当我们在输入栏中输入一些东西时,searchItems 就会运行。
现在,我们需要将输入值传递给searchItems 函数:
<Input icon='search'
placeholder='Search...'
onChange={(e) => searchItems(e.target.value)}
/>
将输入值传递给 searchItems 函数
接下来,让我们将搜索查询接收到函数中,并使用我们之前创建的setSearchInput ,将searchInput 状态设置为这个值:
const searchItems = (searchValue) => {
setSearchInput(searchValue)
}
将searchInput状态设置为searchValue
你可以通过安慰searchValue 来检查它是否有效:

正如你所看到的,我在这里输入了我的名字,它显示在控制台中。
如何根据搜索结果过滤项目
现在,我们要用过滤器的方法来过滤我们的APIData。
const searchItems = (searchValue) => {
setSearchInput(searchValue)
APIData.filter((item) => {
return Object.values(item).join('').toLowerCase().includes(searchInput.toLowerCase())
})
}
根据搜索词过滤APIData
在这个函数searchTerm ,你可以看到我们正在使用filter 方法来过滤出APIData状态,其中包含来自服务器的数据。
我们还使用Object.values ,从对象项中获取数值。
然后,我们使用join(' ') 方法将这些值转换为字符串。
接下来,我们使用toLowerCase 方法将字符串的值改为小写。
最后,我们要检查这个字符串是否包括我们在搜索栏中输入的搜索信息。我们还将其转换为小写字母,以确保如果我们用大写字母输入我们的术语,它会将该字符串转换为小写字母,使搜索更加有效。
然后,我们返回整个查询。
现在我们需要将这个过滤后的数组设置成一个变量:
const filteredData = APIData.filter((item) => {
return Object.values(item).join('').toLowerCase().includes(searchInput.toLowerCase())
})
将过滤后的数据存储到一个const filteredData中
让我们通过安慰它来检查上述功能。所以,搜索一个用户名,你会发现你得到的是该用户名的特别数据:

将搜索项放入控制台
现在,我们需要一个可以存储过滤后的数据的状态。所以,让我们来创建一个:
const [filteredResults, setFilteredResults] = useState([]);
为过滤后的数据创建一个新的状态
创建一个包含我们的过滤数据的状态。
然后在searchItems 函数中用setFilteredResults 将这个状态设置为filteredData :
const searchItems = (searchValue) => {
setSearchInput(searchValue)
const filteredData = APIData.filter((item) => {
return Object.values(item).join('').toLowerCase().includes(searchInput.toLowerCase())
})
setFilteredResults(filteredData)
}
将filteredData设置到filteredResults状态中。
如何在用户界面上显示过滤后的结果
现在,让我们在我们的主用户界面上显示这些过滤后的结果。
首先,我们需要写一些代码,检查我们的搜索输入是否为空,如果是,就显示所有的数据。否则,它将根据搜索输入来过滤它们:
const searchItems = (searchValue) => {
setSearchInput(searchValue)
if (searchInput !== '') {
const filteredData = APIData.filter((item) => {
return Object.values(item).join('').toLowerCase().includes(searchInput.toLowerCase())
})
setFilteredResults(filteredData)
}
else{
setFilteredResults(APIData)
}
}
检查搜索词是否为空
在应用程序的返回部分,我们也需要这个检查。
因此,如果搜索词的长度大于1,我们将显示过滤过的数据。否则,我们将显示存储在API数据状态中的所有数据:
<Card.Group itemsPerRow={3} style={{ marginTop: 20 }}>
{searchInput.length > 1 ? (
filteredResults.map((item) => {
return (
<Card>
<Card.Content>
<Card.Header>{item.name}</Card.Header>
<Card.Description>
{item.email}
</Card.Description>
</Card.Content>
</Card>
)
})
) : (
APIData.map((item) => {
return (
<Card>
<Card.Content>
<Card.Header>{item.name}</Card.Header>
<Card.Description>
{item.email}
</Card.Description>
</Card.Content>
</Card>
)
})
)}
</Card.Group>
检查数据是否有大于1的长度。
现在,如果我们在搜索字段中搜索某个用户名,我们将得到这个特定用户的数据:

在用户界面中获得搜索输入的结果
而如果我们去掉这个名字,我们将得到所有的数据:

如果搜索输入为空,获得所有的数据
下面是所有的代码供你参考:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Card, Input } from 'semantic-ui-react'
export default function Posts() {
const [APIData, setAPIData] = useState([])
const [filteredResults, setFilteredResults] = useState([]);
const [searchInput, setSearchInput] = useState('');
useEffect(() => {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then((response) => {
setAPIData(response.data);
})
}, [])
const searchItems = (searchValue) => {
setSearchInput(searchValue)
if (searchInput !== '') {
const filteredData = APIData.filter((item) => {
return Object.values(item).join('').toLowerCase().includes(searchInput.toLowerCase())
})
setFilteredResults(filteredData)
}
else{
setFilteredResults(APIData)
}
}
return (
<div style={{ padding: 20 }}>
<Input icon='search'
placeholder='Search...'
onChange={(e) => searchItems(e.target.value)}
/>
<Card.Group itemsPerRow={3} style={{ marginTop: 20 }}>
{searchInput.length > 1 ? (
filteredResults.map((item) => {
return (
<Card>
<Card.Content>
<Card.Header>{item.name}</Card.Header>
<Card.Description>
{item.email}
</Card.Description>
</Card.Content>
</Card>
)
})
) : (
APIData.map((item) => {
return (
<Card>
<Card.Content>
<Card.Header>{item.name}</Card.Header>
<Card.Description>
{item.email}
</Card.Description>
</Card.Content>
</Card>
)
})
)}
</Card.Group>
</div>
)
}
搜索过滤器的全部代码。
现在你有了,一个使用React钩子的React的全功能搜索过滤器。
我们经常从后端处理这个功能,在API端点中传递搜索查询参数。但知道如何从前端处理它也很重要。
如果你想补充这篇文章,你也可以查看我的YouTube视频:使用React和React钩子构建一个搜索过滤器。