按姓氏排序数据从React JS中的API获取

时间:2018-03-11 03:15:35

标签: javascript reactjs react-router

Image of table

我正在尝试从随机用户API获取数据并创建用户表。我还想添加按姓氏排序,分页等功能,每页只显示10个项目,如果用户想要查看更多,则添加选项按钮。页面上的10个项目我正在努力建立这个功能,任何他都会感激不尽

import React, { Component } from 'react';

import Loader from '../components/Loader/Loader';

import '../util/Fetch.css';
export class Fetch extends Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [],
      isLoading: true
    };
    this.sortList.bind(this);
    this.compareBy.bind(this);
  }

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    const url =
      'https://randomuser.me/api/?results=20&nat=us,nz,au&seed=foobar';
    fetch(url)
      .then(response => {
        return response.json();
      })
      .then(parsedJSON => {
        this.setState({
          users: parsedJSON.results,
         isLoading: false
        });
      })
        .catch(error => console.log('parsing failed', error));
    }

    compareBy(key) {
      return function(a, b) {
        if (a[key] < b[key]) return -1;
        if (a[key] > b[key]) return 1;
        return 0;
      };
    }

    sortList(key) {
    let arrayCopy = [...this.state.users];
    console.log(
      arrayCopy.map(user => {
        return user.name.first;
      })
    );
    arrayCopy
      .map(user => {
        return user.name.last;
      })
      .sort(this.compareBy(key));
    this.setState({ users: arrayCopy });
  }
}
render() {
const { users } = this.state;

return (
  <div>
    {this.state.isLoading ? (
      <Loader />
    ) : (
      <div className="table-container">
        <div className="pag-header">
          <div>
            <ul className="pag-box">
              <h2>List of Users</h2>
              <li>
                <hr />
              </li>
              <li>
                Sort By:{' '}
                <a onClick={() => this.sortList(this.compareBy, 'last')}>
                  Last Name
                  <span>
                    <i className="fas fa-sort-down" />
                  </span>
                </a>
              </li>
            </ul>
          </div>
          <div>
            <ul className="pag-box">
              <li>
                items per page
                <label>
                  <select>
                    <option value="5">5</option>
                    <option value="10">10</option>
                    <option value="25">25</option>
                    <option value="50">50</option>
                    <option value="75">75</option>
                    <option value="100">100</option>
                  </select>
                </label>
              </li>
              <li>of</li>
              <li>
                <a>
                  <i className="fas fa-angle-left" />
                </a>
              </li>
              <li>
                <a>
                  <i className="fas fa-angle-right" />
                </a>
              </li>
            </ul>
          </div>
        </div>
        <div className="responsive-table">
          <li id="table-head" className="table-header">
            <div className="col col-1">First name</div>
            <div className="col col-2">Last Name</div>
            <div className="col col-3">Country</div>
            <div className="col col-4">Address</div>
            <div className="col col-5">City</div>
            <div className="col col-5">State</div>
            <div className="col col-7">Zip</div>
            <div className="col col-8">Phone</div>
          </li>
          <ul className="responsive-table">
            {users.map(user => (
              <li key={user.id.value} className="table-row">
                <div className="col col-1" data-label="First Name">
                  {user.name.first}
                </div>
                <div className="col col-2" data-label="Last Name">
                  {user.name.last}
                </div>
                <div className="col col-3" data-label="Country">
                  {user.nat}
                </div>
                <div className="col col-4" data-label="Address">
                  {user.location.street}
                </div>
                <div className="col col-5" data-label="Address">
                  {user.location.city}
                </div>
                <div className="col col-6" data-label="State">
                  {user.location.state}
                </div>
                <div className="col col-7" data-label="Zip">
                  {user.location.postcode}
                </div>

                <div className="col col-8" data-label="Phone">
                  {user.cell}
                </div>
              </li>
            ))}
          </ul>
        </div>
      </div>
    )}
   </div>
 );
 }
}

2 个答案:

答案 0 :(得分:1)

编辑:有问题的代码存在许多问题,并且在问题中没有提供足够的信息来真正理解问题的范围。在项目中的多个文件中设计了一个自定义解决方案来解决提问者的问题,但是在这里发布该解决方案超出了本问题的范围。

在最后几行中,您尝试排序arrayCopy.map(user => user.name.last)该地图将返回一个JUST THE LAST NAME的数组,就像['jones', 'smith', 'jenkins']一样。然后你尝试用一个键对那个数组进行排序,但是那个数组是一个简单的字符串数组,而且是唯一的&#34;键&#34;它有索引(0,1,2等)

相反,您应该执行arrayCopy.sort(this.compareBy(key))this.sortList('last')来完成排序并保存到州。

compareBy = (key) => {  // no need to bind arrow functions
  return function(a, b) {
    if (a[key] < b[key]) return -1;
    if (a[key] > b[key]) return 1;
    return 0;
  };
};

sortList = (key) => {
  let arrayCopy = [...this.state.users];
  arrayCopy.sort(this.compareBy(key));
  this.setState({ users: arrayCopy });
};
编辑:在看了你的代码之后,我发现你正在尝试绑定sortListcompareBy,但你实际上并没有在任何地方保存这些绑定方法。 this.sortList.bind(this)返回绑定方法,但不会绑定原始方法,因此每当您调用this.sortList时,它仍然是未绑定的。将其更改为箭头功能(如上所述)将使其始终受约束。

编辑:现在您已经添加了渲染方法,我们可以看到真正的问题在于您的点击处理程序:

 <a onClick={() => this.sortList(this.compareBy, 'last')}>

在这里,您使用两个参数,一个函数(this.compareBy)和一个字符串(&#39; last&#39;)调用this.sortList。 this.sortList只需要一个参数:字符串。这一行应为:

 <a onClick={() => this.sortList('last')}>

此外,由于您在this.sortList处理程序中将onClick作为箭头函数实现,因此您无需在构造函数中绑定sortList方法,因为你的例子(不会像实现的那样工作)或将它转换为箭头函数(正如我在之前的编辑中所建议的那样)。真正的问题是A)点击处理程序传递错误的参数,B)在排序之前将数组映射到字符串数组。

答案 1 :(得分:0)

您可以使用一种简单的方法对数组进行排序;例如

sortList = (key)=>{
 let arrayCopy = [...this.state.users];
 arrayCopy.sort((a,b) => a.name[key] > b.name[key]);
 this.setState({ users: arrayCopy });
}