当我想对redux容器中的数据进行排序或过滤时,我该如何查看它的状态

How can I watch for state of data in redux container, when I want to sort or filter it?

本文关键字:过滤 状态 何查看 排序 redux 数据      更新时间:2023-09-26

我有一些数据作为对象数组。我会用redux对它进行排序或过滤,然后对redux进行反应

我的初始状态

let initialState = {
  persons:[],
  active:0,
  loading:false,
  filter:"",
  field:"name",
  increase:true
}

由于过滤和排序是针对UI的,所以我尝试在容器(智能组件)中实现它。我在阅读redux的文档,在过去的几天里对redux进行了反应,发现我需要使用重新选择。因此,我创建了两个选择器:存储最新排序的数据数组的sortData和存储最新筛选的数据数组的filterData

选择器的参数-选择器监视的字段:

let getPersons = (state) => state.persons
let getFilter = (state) => state.filter
let getField = (state) => state.field
let getIncrease = (state) => state.increase

sortData:

let sortData = createSelector(
  [getPersons, getField,getIncrease],
  (persons,field,increase) =>  {
    console.log("SORT");
    let sortarr = persons.slice(0);
    return sortarr.sort((a , b) => {
      if (a[field] > b[field])  return increase ?  1: -1
      if (a[field] < b[field])  return increase ? -1:1
      return 0
    })
  })

filterData:

let filterData = createSelector(
  [sortData,getFilter],
  (persons,filter) => {
    return persons.filter( p =>{
      console.log("FILTER");
      return p.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1
    })
  },
)
如上所述,我的选择器filterData依赖于sortData,但并非相反。当我过滤数据时,它只调用过滤计算,但当我尝试对数据进行排序时,它同时调用排序和筛选。

我的映射StateToProps

let mapStateToProps = (state) =>{
  let modernState = filterData(state)
  return {
      activePerson:modernState[state.active],
      persons:modernState,
      loading:state.loading,
      active:state.active
    }
}
当我单击"筛选数据"时,我要筛选最新排序的数组,当我单击"排序数据"时,我想对最新筛选的数组进行排序我的问题:

  1. 如何在不重新计算的情况下实现此功能
  2. 我可以在不重新选择的情况下实现它吗

附言:我读过丹·阿布拉莫夫的例子,但不幸的是,我无法将其用于解决我的任务。更多代码:在此处输入链接描述

您可以尝试以下操作,最好将其保存在一个文件中,然后在连接组件时将其用作选择器

// yourComponentSelector.js
let getPersons = (state) => state.persons
let getFilter = (state) => state.filter
let getField = (state) => state.field
let getIncrease = (state) => state.increase
let getLoading = (state) => state.loading
let getActive = (state) => state.active
let sortData = createSelector(
  [getPersons, getField,getIncrease],
  (persons,field,increase) =>  {
    console.log("SORT");
    let sortarr = persons.slice(0);
    return sortarr.sort((a , b) => {
      if (a[field] > b[field])  return increase ?  1: -1
      if (a[field] < b[field])  return increase ? -1:1
      return 0
    })
  })
function filterData(data, filter) {
   return data.filter(p => {
       console.log("FILTER");
       return p.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1
   });
}
let filterDataSelector = createSelector(
   [sortData, filter],
   (persons, filter) => {
      return filterData(persons, filter)
   })
export const yourComponentSelector = createSelector(
  [filterDataSelector,
   getLoading,
   getActive
  ],
  (persons, loading, active) => {
    return {
       persons: persons,
       activePerson: persons[active],
       loading: loading,
       active: active
    }
  },
)

然后在您的组件中

   import { yourComponentSelector } from './yourComponentSelector.js';
   // instead of using your mapStatToProps function you can now use the selector
   export default connect(yourComponentSelector)(yourComponent);

总之

如果您需要对数据进行排序,它将重新计算filteredData,因为sortData已经更改,并且您希望筛选最近排序的数据,如果您的筛选器更改,它将再次计算filterData,而不是sortData。重新选择的工作方式是,只有当传递给createSelector的参数之一发生更改时,它才会重新计算状态,所以在构建选择器时请注意这一点。

我认为选择器的输入错误,所以filterData应该是sortData的输入,getPersons应该是filterData:的输入

let sortData = createSelector(
  [filterDataSelector, getField, getIncrease],
  (persons,field,increase) =>  {
    console.log("SORT");
    let sortarr = persons.slice(0);
    return sortarr.sort((a , b) => {
      if (a[field] > b[field])  return increase ?  1: -1
      if (a[field] < b[field])  return increase ? -1:1
      return 0
    })
  })
function filterData(data, filter) {
   return data.filter(p => {
       console.log("FILTER");
       return p.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1
   });
}
let filterDataSelector = createSelector(
   [getPersons, filter],
   (persons, filter) => {
      return filterData(persons, filter)
})
export const yourComponentSelector = createSelector(
  [sortData,
   getLoading,
   getActive
  ],
  (persons, loading, active) => {
    return {
       persons: persons,
       activePerson: persons[active],
       loading: loading,
       active: active
    }
  },
)