簡體   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