【问题标题】:React: Filtering table based on array of objects state?React:基于对象状态数组的过滤表?
【发布时间】:2020-01-01 06:00:28
【问题描述】:

所以我正在做一个非常简单的个人项目来学习反应。我的“SensorTable”组件中的状态(本质上只是一个react-bootstrap 表,当前包含我的传感器列表(其值如 id/temp/humidity/etc...)。

现在这个组件状态只是一个对象数组(那是我的传感器),我通过axios/fetchGET 请求检索到具有所有这些对象的 JSON API。 GET 请求是在 componentDidMount 上发出的。

在这一点上,我真的对 redux 不太满意,这只是一个熟悉 React 的小玩具应用程序。但是我是否正确猜测排序/过滤此表的正确方法是具有以下功能:

  • 从 API 检索最新数据(也许?)
  • 通过按特定顺序对对象数组进行排序或根据我要使用的任何过滤器类型过滤它们来更新状态(可能通过具有高于或低于或特定值的特定对象键的传感器进行过滤)。然后将新数组返回到该状态?

听起来在理论上对我来说很简单...但componentDidMount 不会在此功能发生后再次触发(将数据重置为原始状态?)。或者,如果我在这些过滤器/排序功能之一中更新状态,是否有办法让它不再重新触发该方法?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    componentDidMount 仅在组件初始化时触发,而不是在进一步渲染时触发,因此您的请求只会触发一次,直到您卸载并重新安装组件(例如,通过导航离开并返回页面)。

    至于更新状态,假设您将响应数据存储在名为sensorData 的状态变量中。如果您在每次用户应用过滤器时设置sensorData,您将丢失数据,因为您实际上是从sensorData 数组中删除项目。这意味着当过滤器被删除时,需要重新获取以重新获得您过滤掉的数据。

    更好的方法是将所有响应数据存储在sensorData 中,并在呈现表格时应用内联过滤器。

    例如:

    {sensorData.filter(d => d.someProp === "someVal").map(d => <TableRowItem />)}
    

    这样,在移除过滤器时,您不必再次访问服务器,UI 会立即更新。

    【讨论】:

    • 好点,否则我需要重新获取所有数据。在这种情况下,d =&gt; d.someProp === "someval" 是什么?
    • 我想一个好主意是将“过滤器/排序”保留为状态值,然后根据该状态值过滤基于它的表。
    • 是的,因此您可以将过滤和排序依据的值保留在状态中。
    • d =&gt; d.someProp === "someVal" 只是过滤器的一个示例。在您的情况下,如果您有一些数据并且每个数据项都有一个属性“名称”,并且您想要过滤项目名称包含某个字符串的所有项目(假设该字符串存储在状态变量“filterNameString” ,然后你会说“找到名称包含此字符串的所有项目”,在代码中这将是:sensorData.filter(d =&gt; d.name.includes(filterNameString))filter 函数就像 forEachmap 函数,但只返回与过滤器匹配的项目数组。
    【解决方案2】:

    在最简单的组件情况下,是的,在 componentDidMount 生命周期函数中进行 API 调用(或任意数量的副作用)。 componentDidMount 仅在安装组件时调用一次。但是,componentDidUpdate 会在状态或道具发生任何更改时被调用。

    示例组件可能如下所示:

    class MyComponent extends Component {
      this.state = {
        data: [];
      };
    
      componentDidMount() {
        getDataFromAPI().then(
          response => setState({
            data: response.data.filter(someFilterFn) // filter result array and store in state
          });
        );
      }
    
      render() {
        <div>
          {this.state.data.map(mapElementFn)}
        </div>
      }
    }
    

    这只是一个示例,您也可以将所有数据存储在状态和过滤器中(根据需要)在渲染函数中。这完全取决于您和您的应用的需求。

    【讨论】:

    • 我猜是上述操作的问题,例如,如果我的桌子上有一个过滤按钮或其他东西,我需要在其他地方过滤,因为 componentDidMount() 只会像你说的那样被调用一次(否则我需要一个完整的页面刷新或什么对吗?)
    • 是的,以上假设您获取一次并进行过滤。如果您按需获取,或者在安装后更改过滤内容,那么您需要将其分离出来。
    【解决方案3】:

    componentDidMount 只触发一个。

    使用状态,您可以在过滤/排序后维护两个键,一个是初始列表和修改列表。 本地排序基于普通的 js 数组排序。 参考:https://moduscreate.com/blog/ext-js-to-react-load-sort-and-filter-data-with-react/

    你可以在本地过滤或依赖远程的东西

    当您使用远程 api 调用进行排序时,您需要使用事件处理程序并显式调用 fetch 调用。

    参考:https://codereviewvideos.com/course/pagination-filtering-and-sorting/video/react-sorting 参考:样品https://github.com/codereviewvideos/react-symfony-3.example/blob/pagination-sort-filter/src/containers/list.js

    同样适用于过滤器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      • 2020-12-11
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 2021-11-21
      • 2020-10-21
      相关资源
      最近更新 更多