繁体   English   中英

使用 map 呈现列表,但根据用户在前端的查询进行过滤

[英]render a list using map but filter base on user's query in frontend

我想实现这个结果: https://resepi-khairulaming.vercel.app/

通过传递查询从后端获取结果很容易,但是在客户端做过滤器怎么样? 我是否需要保持 2 个状态,例如。

const [data, setData] = useState() // setData from api source on onload const [filteredData setFilteredData] = useState(data)

一个是原始来源,另一个是过滤后的来源? 因为用户可以清除查询,而我必须恢复未过滤的数据。

还有比这更好的解决方案吗?

对于半持久性 API 结果,您肯定需要一个 state。 对于要呈现的过滤数据,像您所想的那样拥有另一个 state 是一个常见的选择 - 这没有任何问题。

另一种选择是在渲染之前过滤 API 数据,而不需要额外的 state。

return (
  <div>
    {
      data
        .filter(obj => obj.name.toLowerCase().includes(inputValue.toLowerCase())
        .map( /* etc */

另一个是记忆过滤后的数据,使用 API 中的 state 的依赖数组以及任何过滤它的内容。

const [data, setData] = useState([]);
const filteredData = useMemo(
  () => data.filter(obj => obj.name.toLowerCase().includes(inputValue.toLowerCase())
  [data, inputValue]
);

上面使用的inputValue s 和.name s 只是示例 - 替换为您实际的过滤机制。

不是每次用户尝试搜索值时都设置和恢复过滤后的 state,记忆可能是一个可能且更好的选择。

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

const Home = () => {
    const [data, setData] = useState([]);
    const [searchVal, setSearchVal] = useState('')

    const filteredData = useMemo(() => {
        if (searchVal.trim() === '') {
            return data;
        }
        return data.filter(dataItem => dataItem.name === searchVal);
    }, [data, searchVal])

    // use the filteredData in your list..
}

所以你想优化搜索行为。

根据您发送的示例,这是我注意到的情况,以下是一些优化建议:

  1. 搜索会在keydownonchange事件上立即触发,没有延迟,这可能不是理想的实现方式。 在这种情况下,您想要throttledebounce 查找这些术语。 他们将为您节省多个 API 电话。 他们将帮助做的是运行 API 查询,仅当用户停止输入 X 时间时,否则不要。
  2. 这是对数据库的 API 调用。 在生产中,您可能希望使用 ElasticSearch 或在 memory 中存储索引的搜索引擎。
  3. 您还可以缓存大多数搜索结果并首先命中缓存,如果未命中,则查询数据库。 选项:Redis、Memcached、ElastiCache、ElasticSearch。
  4. 将数据保存在 state 中不是一个好的选择,除非记录数更少。 如果它达到数千,你不会想对你的数据库进行如此昂贵的调用然后保持它。

供您阅读的其他资源:全文搜索(这就是所谓的预期行为)

立即修复的建议:在每次 onchange 后调用数据库(如果可能,尝试实现去抖以节省 API 调用,这很容易)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM