【问题标题】:How to sort the data in asc and desc order in table如何在表格中按升序和降序对数据进行排序
【发布时间】:2019-03-05 05:32:20
【问题描述】:

我是反应 js 的新手。在这里,我尝试在用户单击图标时对数据进行排序。

<th scope="col">Technology <i className="fa fa-fw fa-sort sort-icon"></i></th>

所以,现在我有了对象数组形式的数据。

在此,我有 5 列,每列都有排序图标。那么,我该如何使用 react 来实现这个东西呢?

我想按字母顺序排序。

我的数据看起来像,

[{
        "id": "5b7d4a566c5fd00507501051",
        "hrmsJdId": null,
        "companyId": null,
        "jdName": "Senior/ Lead UI Developer",
        "jobDescription": null,
        "technology": java,
    }, {
        "id": "5b7fb04d6c5fd004efdb826f",
        "hrmsJdId": null,
        "companyId": null,
        "jdName": "Content Innovation Lead",
        "jobDescription": null,
        "technology": css
    }, {
        "id": "5b7fb0b26c5fd004efdb8271",
        "hrmsJdId": null,
        "companyId": null,
        "jdName": "Urgent Opening for DSP Engineer/ Senior Engineer for",
        "jobDescription": null,
        "technology": react,
    }]

 <td>{item.technology}</td>
                <td>17</td>
                <td title={item.jdName} className="jd-name-container justify-content-center align-items-center">
                  <div className="jdName">{item.jdName}</div>
                  {(key + 1 === 1) && <div className="badge new-badge badge-warning-custom">New</div>}
                </td>

这就是我呈现数据的方式。现在,

默认情况下,我使用

对其进行排序
   <tbody className="text-center">
          {props.jobList && props.jobList && props.jobList.length > 0 && props.jobList.sort((a, b) => b.createdAt - a.createdAt).map((item, key) => {
            return (
              <tr key={key}>
                <td align="center"> <input type="checkbox" name="myTextEditBox" value="checked" /></td>
                <td>{item.technology}</td>
                <td>17</td>
                <td title={item.jdName} className="jd-name-container justify-content-center align-items-center">
                  <div className="jdName">{item.jdName}</div>
                  {(key + 1 === 1) && <div className="badge new-badge badge-warning-custom">New</div>}
                </td>
                <td>30</td>
                <td>30</td>
                <td>
 </tbody>

那么,我该如何实现呢?

我所做的是,

<th scope="col">Technology<i className="fa fa-fw fa-sort sort-icon" onClick={props.sortAscending('Technology')}></i></th>

然后在容器中

    sortData = (key,event) => {
        console.log("key is,", key);
        this.props.sortAscending(key);
      }

<UserJobsTabel jobList={filteredList} sortAscending={this.sortData} />

作为道具传递。

现在正在行动,

export const sortAscending = (type) => {
  return {
    type: "SORT_ASCENDING",
    payload: type
  }
}

在减速器中,

case FETCHING_JOBDESCRIPTION_SUCCESS:
            return {
                ...state,
                jobList: action.data.jobData ? action.data.jobData.sort((a, b) => b.createdAt - a.createdAt) : action.data.jobData,
                yesterDayScore: action.data.yesterdayScore,
                todayScore: action.data.todayScore,
                error: false,
            }

 case "SORT_ASCENDING": 
          const { sortKey } = action.payload;
            const jobList = [ ...state.jobList ]
        .sort((a, b) => a[sortKey].localeCompare(b[sortKey]));
      return { ...state, jobList };

×

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

我收到此错误。

【问题讨论】:

  • 您要为排序设置默认值还是要将排序保存在State
  • 实际上,当我获取该数据时,默认情况下我想使用 descendng 顺序设置它。我基于 createdDate 属性执行此操作。现在,我使用 created Date 的道具来做。/

标签: javascript reactjs redux react-redux


【解决方案1】:

使用localeCompare() 按字母顺序排序。

在组件仅调度“排序”操作时在 reducer 中完成排序。每次重新排序都会导致 jobList 的组件重新渲染 prop(在 mapStateToProps 中)更新。

在减速器中:

const initialState = {
  jobList: [],
};

export const jobList = (state = initialState, action) => {
  switch(action.type) {
    case Action.SORT_ALPHA_ASC:
      const { sortKey } = action.payload;
      const jobList = [ ...state.jobList ]
        .sort((a, b) => a[sortKey].localeCompare(b[sortKey]));

      return { ...state, jobList };

    default:
      return state;
  }
}

在您的组件中:

// alphaSort will dispatch action: SORT_ALPHA_ASC
const { jobList, alphaSort } = this.props;
if (! jobList || jobList.length < 1) {
  // no job list
  return null;
}

return (
<table>
  <thead>
    { /* TODO: use th/td */ }
    <SomeIcon name='asc-technology' onClick={() => alphaSort('technology')} />
    <SomeIcon name='asc-jdname' onClick={() => alphaSort('jdName')} />
    { /* TODO: other fields */ }
  </thead>
  <tbody>
  {
    jobList.map((job) => ({
      <tr key={job.id}>
        <td name="technology">{job.technology}</td>
        <td title={job.jdName}>
          <div className="jdName">{job.jdName}</div>
        </td>
        { /* TODO: other fields */ }
      </tr>
    }))
  }
  </tbody>
</table>
);

注意: 降序 alpha 排序和其他字段将让 OP 继续。 :)

【讨论】:

  • 所以这里我有 5 列。并且排序在每一列上。
  • @ganesh,请参阅更新为使用表示列的排序键。
  • 这很好,但我认为我们不应该创建一个函数来将jobList 的值从props 映射到state。这是因为这个解决方案会影响性能。我的解决方案是当用户点击标题时,我们应该dispatchaction 来更新state,然后写一个selector 来更新道具
  • 所以我在想,我会有 3 个动作。一种将设置默认状态。这意味着我必须根据上次创建的日期显示数据。因此,首先,一旦我获得数据,我将调度一个将数据设置为默认值的操作。下一步单击升序和降序。选项我将使用两个差异操作更新相同的数据。
  • @ganesh,是的,这就是要走的路。三个动作:init/fetch、asc 排序、desc 排序。
【解决方案2】:

React Js 数组有排序功能:

['b', 'a'].sort((e1, e2) => e1.id < e2.id  ? 1 : - 1)

如果 lambda 函数返回 0,它什么也不做。否则,数组中的两个元素将按返回值的符号排序。

如果数据库中有重复的 ID,则该函数将返回 0。

要交换顺序,请将返回值的符号或“小于”运算符更改为大于运算符。

【讨论】:

    猜你喜欢
    • 2016-10-18
    • 1970-01-01
    • 2020-11-09
    • 2018-10-09
    • 2013-08-15
    • 2011-12-02
    • 2018-05-03
    • 2015-08-30
    相关资源
    最近更新 更多