【问题标题】:What is the best way to filter data in React?在 React 中过滤数据的最佳方法是什么?
【发布时间】:2025-12-10 20:25:03
【问题描述】:

我正在建立该国的餐馆目录。 API 返回一个对象数组,每个对象由 restaurantName、restaurantLocation、restaurantPriceRange 等字段组成。

我想创建一个过滤组件,它将餐厅数组减少为仅包含与搜索条件匹配的餐厅的子集。我还需要通过 URL 传递过滤器值,我认为我应该使用路由器。

我正在考虑使用 useState 挂钩存储初始数据集,然后使用 useReducer 存储活动过滤器选择和过滤后的餐厅集合的子集,其中仅匹配搜索条件,但我觉得这是一个笨拙的解决方案,实际上,我会复制整个餐厅集合的一个子集。

但是,如果我不使用 useState 将初始数据集存储在单独的对象中,则一旦应用过滤器,所有不匹配的内容将永远消失。

实现这一目标的最佳方法是什么?

免责声明:我知道如何在 JavaScript 中过滤数组,并且完全了解过滤器、映射、排序等功能。这个问题是关于 React 生态系统的,什么是构建我的最干净、最简单和最好的方法React 应用程序中的代码。我知道当我为它编写代码时,我仍然必须在我的 reducer 中使用 Array.prototype.filter。

【问题讨论】:

  • Array.prototype.filter() 创建新数组google.com/…
  • 也许我应该更具体一些。这个问题纯粹是关于 React 生态系统的,我正在寻找一个最干净、最简单和最容易维护的解决方案。我已经知道如何使用 vanilla JS 过滤原始 JS 对象。我专门询问有关 React API 的建议。谢谢。
  • 但是 React 使用像 Array.prototype.map() 这样的 js 来显示列表组件,react 是 MVC 的 V 仅此而已,换句话说:你在 js 上处理数据
  • react 是 javascript,filter 是最好的方法,没有 react 助手或内置方法来过滤数组。它同样使用 javascript
  • 感谢您的评论。你能建议 React 组件的结构吗?

标签: reactjs state filtering use-state use-reducer


【解决方案1】:

你在征求意见,所以这是我的。 React 状态(无论是 useState 还是 useReducer)应该只用于有状态的值——改变并导致渲染数据改变的值。过滤后的餐馆列表不是有状态的值。 filters 是一个有状态的值,过滤后的列表是从该状态派生的。过滤后的列表应该是您在每次渲染时生成的常量。如果您的组件中有其他状态或道具发生变化,但不会影响过滤列表,您可以使用 useMemo 挂钩来记忆过滤列表,以防止不必要的重新计算。

伪代码

import React, {useMemo} from “react”;
import {useLocation} from “react-router-dom”;

export const MyComponent = ({restaurants}) => {

   const location = useLocation();

   const filteredRestaurants = useMemo( () => {
       return restaurants.filter( /* some code */ );
   }, [location, restaurants] ); //dependency on location and restaurants 

   return (
      <Wrapper>
        <EditFiltersComponent />
        <List>
           {filteredRestaurants.map( restaurant => 
              <Restaurant {...restaurant} />
           )}
        </List>
      </Wrapper>
   )
}

【讨论】:

    【解决方案2】:

    一般我们从 props 中获取数据

    const OurComponent = ({data, filter}) => { . . .
    

    const { filter } = useParams(); // via query string
    

    您也可以在此组件中过滤输入字段,然后将其值存储在本地状态中以进行重新渲染。

    对于复杂的过滤器,最好有过滤器功能:

    const filterFunc = ({address}) => {
      address.toLowerCase().includes(filter.address.toLowerCase());
    }
    

    渲染会像

    return (
      <ul>
        { 
          data.filter(filterFunc).map({id, name, address} => (
            <li key={id}>{`${name} - ${address}`}</li> 
          ))
        }
      </ul>
    ) 
    

    【讨论】: