当你向 API 发送 GET 请求时,你会从服务器获取响应数据。但有时管理这些数据可能是一个问题。

在这篇文章中,我将向你展示如何在 React 中创建搜索过滤器。它将使用功能组件和 React Hooks 在数据中搜索特定的词。

如何向 API 发出 GET 请求

首先,让我们向 API 发出 GET 请求,该 API 将从服务器获取一些数据。你可以使用任何你喜欢的服务器,但在本文中,我将使用 {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 占位符中获取用户列表
Screenshot-2021-08-14-202008
在顶部获取用户列表和搜索输入

如果你不知道如何在 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 函数绑定到 Input 字段

因此,每当我们在输入字段中输入内容时,searchItem 就会运行。

现在,我们需要将输入值传递给 searchItem 函数。

<Input icon='search'
                placeholder='Search...'
                onChange={(e) => searchItems(e.target.value)}
            />
将输入值传递给 searchItems 函数

接下来,让我们将搜索查询接收到函数中,并使用我们之前创建的 setSearchInputsearchInput 状态设置为此值。

const searchItems = (searchValue) => {
        setSearchInput(searchValue)
    }
将 searchInput 状态设置为 searchValue

你可以通过在控制台操作 searchValue 来检查它是否正在运行。

Screenshot-2021-08-14-203750

如你所见,我在此处输入我的名字,它显示在控制台中。

如何根据搜索结果过滤项目

现在,我们将使用 filter 方法过滤掉 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())
})
将过滤后的数据存储到常量 filteredData 中

让我们通过在控制台操作它来检查上述功能。搜索用户名,你将获得该用户名的数据。

Screenshot-2021-08-14-211709
将搜索项放入控制台

现在,我们需要一个可以存储过滤数据的状态。所以,让我们创建一个。

const [filteredResults, setFilteredResults] = useState([]);
过滤数据的新状态

创建一个包含过滤数据的状态。

然后使用 setFilteredResultssearchItems 函数中将此状态设置为 filtersData

const searchItems = (searchValue) => {
        setSearchInput(searchValue)
        const filteredData = APIData.filter((item) => {
            return Object.values(item).join('').toLowerCase().includes(searchInput.toLowerCase())
        })
        setFilteredResults(filteredData)
    }
将 filteredData 设置为 filteredResults 状态

如何在用户界面中显示过滤结果

现在,让我们在主 UI 中显示这些过滤后的结果。

首先,我们需要编写一些代码来检查我们的搜索输入是否为空,如果是,则显示所有数据。 则,它将根据搜索输入过滤它们。

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

现在,如果我们在搜索字段中搜索某个用户名,将获得该特定用户的数据。

Screenshot-2021-08-14-212917
在 UI 中获取搜索输入的结果

如果我们删除名称,将获得所有数据。

Screenshot-2021-08-14-213037
如果搜索输入为空,则获取所有数据

以下代码供你参考:

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 Hooks 的全功能搜索过滤器。

我们通常通过在 API 端点中传递搜索查询参数来从后端处理此功能。但了解如何从前端处理它也很重要。

如果你想拓展相关知识,可以查看我的 YouTube 视频:使用 React 和 React Hooks 构建搜索过滤器

感谢你阅读本文。

原文:How to Build a Search Filter using React and React Hooks,作者:Nishant Kumar