首页 > 解决方案 > 在 React 中创建了多过滤按钮,但每次单击其他过滤按钮时列表都不会显示

问题描述

我成功创建了多个过滤按钮。但是,我注意到,当我第一次单击一个过滤按钮显示居住在英国的学生时,列表显示过滤结果,然后我单击另一个过滤按钮显示居住在美国的学生,列表只是空白,我的控制台显示数组是空的。我不知道发生了什么。

import React, { Component } from 'react';
import profiles from '../data/berlin.json';

export class FaceBook extends Component {
  constructor(props){
    super(props);
    this.state = {
        profilelist: profiles,
        filtered: profiles
    }
}
showProfile = () =>{
  return this.state.profilelist.map((eachProfile,i)=>{
    let studentBoolean;
    if(eachProfile.isStudent) {
      studentBoolean = "Student";
    } else {studentBoolean = "Teacher"}
      return(
        <div className="profilecard" key={i}>
          <div className="profileimage"><img src={eachProfile.img} alt="Actor"/></div>
          <div className="profilecontent">
            <ul>
              <li><strong>First Name:</strong> {eachProfile.firstName}</li>
              <li><strong>Last Name:</strong> {eachProfile.lastName}</li>
              <li><strong>Country:</strong> {eachProfile.country}</li>
              <li><strong>Type:</strong> {studentBoolean}</li>
            </ul>
          </div>
      </div>
      )
  })
}
showAll = () =>{

  this.setState({
    profilelist: profiles
  })
}

showEngland = () =>{
  this.setState({
    profilelist: profiles,
    filtered: profiles
  })
  let filterEngland = [...this.state.profilelist];

  let newList = filterEngland.filter(item => {
    const lc = item.country.toLowerCase();
    const filter = "england";
    return (lc === filter);
  })
  console.log(newList);
  this.setState({
    profilelist: newList,
    filtered: newList
  })
}

showUSA = () =>{
  this.setState({
    profilelist: profiles,
    filtered: profiles
  })

  let filterUSA = [...this.state.profilelist];

  let newusaList = filterUSA.filter(item => {
    const lc = item.country.toLowerCase();
    const filter = "usa";
    return (lc === filter);
  })
  this.setState({
    profilelist: newusaList,
    filtered: newusaList
  })
}

  render() {
    console.log(this.state.profilelist);
    return (
      <div>
      <div className="menubar">
        <button onClick={this.showAll}>All</button>
        <button onClick={this.showEngland}>England</button>
        <button onClick={this.showUSA}>USA</button>
      </div>
      <div className="profileTable">
      {this.showProfile()}
      </div>

      </div>
    )
  }
}

export default FaceBook

如您所见,我创建了 3 个按钮“All”、“England”、“USA”。我还为每个按钮创建了 3 个函数。当英国和美国显示过滤结果时,all按钮重置。state.profilelist我试图添加

this.setState({
    profilelist: profiles,
    filtered: profiles
  })

在英格兰和美国的功能开始时,它会在过滤之前重置列表,但它不起作用....

标签: javascriptreactjs

解决方案


您不需要为每个过滤器创建一个函数,只需创建一个处理所有过滤的函数。不要修改profilelist所有过滤应该修改 filtered数组。

// filter profiles by country
filterByCountry = country => {

  if (!country || typeof country !== "string") {
    return;
  }

  this.setState(prevState => {
    return {
      filtered:
        country.toLowerCase() === "all"
          ? this.state.profilelist
          : prevState.profilelist.filter(
              item =>
                item &&
                item.country &&
                item.country.toLowerCase() === country.toLowerCase()
            )
    };
  });
};

显示配置文件功能

showProfile = () => {
  return this.state.filtered.map((eachProfile, i) => (
    <div className="profilecard" key={i}>
      <div className="profileimage">
        <img src={eachProfile.img} alt="Actor" />
      </div>
      <div className="profilecontent">
        <ul>
          <li>
            <strong>First Name:</strong> {eachProfile.firstName}
          </li>
          <li>
            <strong>Last Name:</strong> {eachProfile.lastName}
          </li>
          <li>
            <strong>Country:</strong> {eachProfile.country}
          </li>
          <li>
            <strong>Type:</strong>{" "}
            {eachProfile.isStudent ? "Student" : "Teacher"}
          </li>
        </ul>
      </div>
    </div>
  ));
};

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script>

const profiles = [
  {
    firstName: "James",
    lastName: "Peter",
    country: "England",
    isStudent: true,
    img: "https://img.icons8.com/officel/16/000000/edit-user-female.png"
  },
  {
    firstName: "Jane",
    lastName: "Jones",
    country: "usa",
    isStudent: false,
    img: "https://img.icons8.com/officel/16/000000/edit-user-female.png"
  },
  {
    firstName: "Michael",
    lastName: "Ballack",
    country: "Germany",
    isStudent: false,
    img: "https://img.icons8.com/officel/16/000000/edit-user-female.png"
  },
  {
    firstName: "Mary",
    lastName: "Jane",
    country: "England",
    isStudent: false,
    img: "https://img.icons8.com/officel/16/000000/edit-user-female.png"
  },
  {
    firstName: "Charlie",
    lastName: "Barack",
    country: "usa",
    isStudent: true,
    img: "https://img.icons8.com/officel/16/000000/edit-user-female.png"
  },
  {
    firstName: "Will",
    lastName: "Ozil",
    country: "Germany",
    isStudent: true,
    img: "https://img.icons8.com/officel/16/000000/edit-user-female.png"
  }]
  
</script>

<script type="text/babel">

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      profilelist: profiles,
      filtered: profiles
    };
  }
  
  filterByCountry = country => {
    if (!country || typeof country !== "string") {
      return;
    }

    this.setState(prevState => {
      return {
        filtered:
          country.toLowerCase() === "all"
            ? this.state.profilelist
            : prevState.profilelist.filter(
                item =>
                  item &&
                  item.country &&
                  item.country.toLowerCase() === country.toLowerCase()
              )
      };
    });
  };

  showProfile = () => {
    return this.state.filtered.map((eachProfile, i) => (
      <div className="profilecard" key={i}>
        <div className="profileimage">
          <img src={eachProfile.img} alt="Actor" />
        </div>
        <div className="profilecontent">
          <ul>
            <li>
              <strong>First Name:</strong> {eachProfile.firstName}
            </li>
            <li>
              <strong>Last Name:</strong> {eachProfile.lastName}
            </li>
            <li>
              <strong>Country:</strong> {eachProfile.country}
            </li>
            <li>
              <strong>Type:</strong>{" "}
              {eachProfile.isStudent ? "Student" : "Teacher"}
            </li>
          </ul>
        </div>
      </div>
    ));
  };

  render() {

    return (
      <div>
        <div className="menubar">
          <button onClick={() => this.filterByCountry("All")}>All</button>
          <button onClick={() => this.filterByCountry("England")}>
            England
          </button>
          <button onClick={() => this.filterByCountry("usa")}>USA</button>
        </div>
        <div className="profileTable">{this.showProfile()}</div>
      </div>
    );
  }
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
);
</script>


推荐阅读