javascript - 在 React 中处理巨大的 10 列表排序的最佳方法?

标签 javascript reactjs redux

所以基本上我有一个巨大的项目列表,我想将其放入动态表中。单击表头时,将调用我的handleSort 函数。单击的目标还将一个参数传递给我的handleSort函数,告诉它单击了哪个标题。我的应用程序完全符合我的要求,唯一的问题是我知道这是实现我需要的一种 super 笨拙的方式。下面是我的状态和我的handleSort函数:

class ChampionsOverview extends Component {
  constructor(props) {
    super(props);
    this.state={
      champions: [],
      updated: false,
      loading: true,
      currentSort: 'costAscending',
      name: '',
      traits: '',
      cost: ' ascending',
      health: '',
      armor: '',
      magicResist: '',
      dps: '',
      attackDamage: '',
      attackSpeed: '',
      range: ''
    }
    this.handleSort = this.handleSort.bind(this);
  }

  handleSort(event, header){
    switch(header) {
      case 'name':
        (this.state.currentSort === 'nameAscending' ? this.setState({ currentSort: 'nameDescending', name: ' descending', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'nameAscending', name: ' ascending', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'traits':
        (this.state.currentSort === 'traitsAscending' ? this.setState({ currentSort: 'traitsDescending', name: '', traits: ' descending', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'traitsAscending', name: '', traits: ' ascending', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'cost':
        (this.state.currentSort === 'costAscending' ? this.setState({ currentSort: 'costDescending', name: '', traits: '', cost: ' descending', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'costAscending', name: '', traits: '', cost: ' ascending', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'health':
        (this.state.currentSort === 'healthAscending' ? this.setState({ currentSort: 'healthDescending', name: '', traits: '', cost: '', health: ' descending', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'healthAscending', name: '', traits: '', cost: '', health: ' ascending', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'armor':
        (this.state.currentSort === 'armorAscending' ? this.setState({ currentSort: 'armorDescending', name: '', traits: '', cost: '', health: '', armor: ' descending', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'armorAscending', name: '', traits: '', cost: '', health: '', armor: ' ascending', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'magicResist':
        (this.state.currentSort === 'magicResistAscending' ? this.setState({ currentSort: 'magicResistDescending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: ' descending', dps: '', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'magicResistAscending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: ' ascending', dps: '', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'dps':
        (this.state.currentSort === 'dpsAscending' ? this.setState({ currentSort: 'dpsDescending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: ' descending', attackDamage: '', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'dpsAscending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: ' ascending', attackDamage: '', attackSpeed: '', range: '' }));
        break;
      case 'attackDamage':
        (this.state.currentSort === 'attackDamageAscending' ? this.setState({ currentSort: 'attackDamageDescending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: ' descending', attackSpeed: '', range: '' }) : this.setState({ currentSort: 'attackDamageAscending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: ' ascending', attackSpeed: '', range: '' }));
        break;
      case 'attackSpeed':
        (this.state.currentSort === 'attackSpeedAscending' ? this.setState({ currentSort: 'attackSpeedDescending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: ' descending', range: '' }) : this.setState({ currentSort: 'attackSpeedAscending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: ' ascending', range: '' }));
        break;
      case 'range':
        (this.state.currentSort === 'rangeAscending' ? this.setState({ currentSort: 'rangeDescending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: ' descending' }) : this.setState({ currentSort: 'rangeAscending', name: '', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: ' ascending' }));
        break;
      default:
        this.setState({ currentSort: 'costAscending', cost: ' ascending' });
    }
  }

基本上,我获取事件传递给我的 header ,并确定 currentSort 应该是什么。如果当前处于事件状态的 header 相同,我会反转当前排序。

currentSort 确定我的项目的顺序,而名称、成本和运行状况等其他状态则确定表标题旁边显示的图标。

任何关于如何清理我的代码的建议我们都百分百感激。这种困惑的局面快要了我的命。

更新1

<th id='ChampionOverviewMobile-table-header-row-name' className='ChampionOverviewMobile-table-header-row-item' onClick={event => this.handleSort(event, 'name')}>Name&nbsp;<Icon name={`sort${this.state.name}`}/></th>

最佳答案

我认为你可以进行一些优化。首先,设置状态时不需要指定每个状态 Prop 。例如,而不是这样:

this.setState({ currentSort: 'nameDescending', name: ' descending', traits: '', cost: '', health: '', armor: '', magicResist: '', dps: '', attackDamage: '', attackSpeed: '', range: '' });

你可以这样做:

this.setState({ currentSort: 'nameDescending', name: ' descending' }));

下一个优化是您的状态似乎有冗余信息。为什么 currentSort 等于 nameDescending 并且 name 等于 descending?相反,如果您只有一个 direction 键和一个 currentSort 键怎么办?然后,您的 handleSort 函数可以大大简化:

handleSort(event, header) {
  const direction = header === this.state.currentSort ?
    this.state.direction * -1 : 1
  this.setState({  currentSort: header, direction });
}

现在,this.state.direction 将是 1(升序)或 -1(降序)。 this.state.currentSort 会告诉您要对哪一列进行排序。

图标名称

您可以在 render 方法中派生图标名称,而不是在状态中冗余存储图标名称。例如:

render() {
  const direction = this.state.direction === 1 ? "Ascending" : "Descending";
  const iconName = this.state.currentSort + direction;
  return <Icon name={`sort${iconName}`} />
}

关于javascript - 在 React 中处理巨大的 10 列表排序的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58965913/

相关文章:

Javascript 事件调用者未被传递到参数中

javascript - iphone html动画?

javascript - React 列表的无限滚动

javascript - 如何不在React Native中将搜索结果保存在redux-persist中?

reactjs - 如何根据不同的属性对 React 组件列表进行排序?

javascript - 外部加载的 svg 文件元素的 id

javascript - 添加链接时 Bootstrap 下拉按钮将不起作用

javascript - React Native 未定义不是一个函数

reactjs - React 组件在重新渲染时会重置其状态吗?

javascript - React : this. props.posts.map 不是一个函数