如何使用React和React Hooks建立一个搜索过滤器

383 阅读5分钟

当你向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钩子构建一个搜索过滤器