反应-按性别或年龄过滤列表

时间:2019-09-13 08:40:07

标签: javascript reactjs

我从以下api中获得了具有名称,性别,年龄等的用户列表:[https://gorest.co.in/public-api/users]。目前,我可以按gender === female进行过滤,但是当我针对gender === male进行过滤时不起作用。

此外,我尝试按年龄过滤用户列表。我知道了出生日期,然后进行了排序,但这似乎还不够。

我有一个LIVE EXAMPLE HERE

这是代码:

import React from "react";
import axios from "axios";

export default class UserList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      list: [],
      search: ""
    };
  }

  componentDidMount() {
    this.getList();
  }

  /* get users list */
  getList = async () => {
    const api = 'https://gorest.co.in/public-api/users?_format=json&access-token=3qIi1MDfD-GXqOSwEHHLH73Y3UitdaFKyVm_';

    await axios
      .get(api)
      .then(response => {
        const list = response.data.result;
        this.setState({
          list,
          isLoading: false
        });
      })
      .catch(err => {
        console.log(err);
      });
  };

  /* handler for search bar */
  handleChange = e => {
    this.setState({
      search: e.target.value
    });
  };

  filterGender = gender => {
    const lowerCaseGender = gender.toLowerCase();
    const filteredGender = this.state.list.filter(
      user => user.gender.toLowerCase().indexOf(lowerCaseGender) !== -1
    );

    this.setState({ list: filteredGender }, () => console.log(this.state.list));
  };

  filterAge = () => {
    const ageList = this.state.list.map(age => {
      return age.dob;
    });

    const filteredAge = this.state.list.filter(
      e => e.dob.indexOf(ageList) !== -1
    );

    this.setState({ list: filteredAge }, () => console.log(this.state.list));
  };

  render() {
    let style = {
      display: "grid",
      gridTemplateColumns: "repeat(auto-fill, minmax(250px, 1fr))",
      padding: "1rem",
      gridGap: "1rem 1rem"
    };

    return (
      <div>
        <input
          placeholder="Search for a user..."
          onChange={e => this.handleChange(e)}
        />
        <button onClick={() => this.filterGender("male")}>Male</button>
        <button onClick={() => this.filterGender("female")}>Female</button>
        <button onClick={() => this.filterAge()}>Age</button>
        <ul style={style}>
          {this.state.list.map(user => {
            return (
              <li key={user.id}>
                <div>
                  <img className="thumb" alt="" src={user._links.avatar.href} />
                </div>

                <div className="userInfo">
                  <p>
                    {user.first_name} {user.last_name}
                  </p>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
    );
  }
}

谢谢!

3 个答案:

答案 0 :(得分:1)

您正在使用的条件

user.gender.toLowerCase().indexOf(lowerCaseGender) !== -1

由于male而与female中的indexOf相匹配。

您应该这样做

const filteredGender = this.state.list.filter(
      user => user.gender.toLowerCase() === lowerCaseGender
);

答案 1 :(得分:0)

您的代码中有两个问题。

在这里,我已经更新了您的代码。
https://codesandbox.io/s/epic-swartz-iu3qp

问题1: filterGender 函数中使用indexOf

解决方案1:直接比较性别,而不是indexOf

const filteredGender = this.list.filter(
    user => user.gender.toLowerCase() === lowerCaseGender
);


问题2::您正在从this.state.list变量中过滤记录,然后在同一state变量中对其进行更新。

解决方案2:this.list中使用另一个变量constructor并使用它来过滤记录。

constructor中定义变量

constructor(props) {
    super(props);

    this.state = {
      list: [],
      search: ""
    };
    this.list = []; // define new list here...
  }

您必须在 getList 函数

中将即将到来的列表分配给this.list变量
this.list = response.data.result;

getList函数应如下所示。

getList = async () => {
    const api =
      "https://gorest.co.in/public-api/users?_format=json&access-token=3qIi1MDfD-GXqOSwEHHLH73Y3UitdaFKyVm_";

    await axios
      .get(api)
      .then(response => {
        this.list = response.data.result; // assign list in variable
        this.setState({
          list:this.list,
          isLoading: false
        });
      })
      .catch(err => {
        console.log(err);
      });
  };

现在,您必须更新以下两个过滤器功能。代替this.state.list,请使用this.list

filterGender = gender => {
    const lowerCaseGender = gender.toLowerCase();
    const filteredGender = this.list.filter(
      user => user.gender.toLowerCase() === lowerCaseGender
    );

    this.setState({ list: filteredGender }, () => console.log(this.state.list));
  };

  filterAge = () => {
    const ageList = this.list.map(age => {
      return age.dob;
    });

    const filteredAge = this.list.filter(
      e => e.dob.indexOf(ageList) !== -1
    );

    this.setState({ list: filteredAge }, () => console.log(this.state.list));
  };

希望这对您有用!

答案 2 :(得分:0)

在相同环境中具有正确代码的完整工作演示

性别

  

问题-indexOf函数的使用无法达到任何目的。

     

解决方案-:

     

使用简单的Array.filter并保持性别平等。

     

此功能需要更改为性别过滤器-:

  filterGender = gender => {
    const filteredGender = this.state.list.filter(
      user => user.gender.toLowerCase() === gender
    );
    this.setState({ list: filteredGender }, () => console.log(this.state.list));
  };

年龄

  

问题-筛选对排序数据没有帮助。

     

解决方案-:

     

使用Array.sort并添加比较器功能。

     

此功能需要更改以进行年龄排序-:

  filterAge = () => {
    const filteredAge = this.state.list.sort(function(a, b) {
      return new Date(b.dob) - new Date(a.dob);
    });

    this.setState({ list: filteredAge }, () => console.log(this.state.list));
  };