在 React Js 中使用多个复选框过滤列表

Filter The List Using Multiple CheckBoxes in React Js

大家好,我正在尝试根据条件过滤复选框 onClick 的对象数组列表,但是我在 handle 方法中的其他条件返回给我一个相同的数组,状态没有改变,所以我想要默认列表,当我尝试取消选中所有列表时删除筛选列表。

import React from "react";
import "./Search.css";

class Search extends React.Component {
  constructor() {
    super();
    this.state = {
      searchLists: [
        {
          id: 1,
          type: "All",
          name: "Akash",
          location: "bangalore",
          experience: 1
        },
        {
          id: 2,
          type: "FullTime",
          name: "feroz",
          location: "mumbai",
          experience: 3
        },
        {
          id: 3,
          type: "PartTime",
          name: "Farheen",
          location: "agra",
          experience: 5
        },
        {
          id: 4,
          type: "Freelancer",
          name: "Raju",
          location: "chennai",
          experience: 6
        },
        {
          id: 5,
          type: "All",
          name: "Asif",
          location: "vegas",
          experience: 7
        }
      ],
      checked: false
    };
  }

  handleAll = () => {
    console.log("i clicked");
    if (this.state.checked === false) {
      const filteredAll = this.state.searchLists.filter(
        item => item.type === "All"
      );

      console.log(filteredAll);
      this.setState({ searchLists: filteredAll, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  handleFullTime = () => {
    if (this.state.checked === false) {
      const filteredFullTime = this.state.searchLists.filter(
        item => item.type === "FullTime"
      );
      console.log(filteredFullTime);
      this.setState({ searchLists: filteredFullTime, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  handlePartTime = () => {
    if (this.state.checked === false) {
      const filteredPartTime = this.state.searchLists.filter(
        item => item.type === "PartTime"
      );
      console.log(filteredPartTime);
      this.setState({ searchLists: filteredPartTime, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  handleFreelancer = () => {
    if (this.state.checked === false) {
      const filteredFreelancer = this.state.searchLists.filter(
        item => item.type === "Freelancer"
      );
      console.log(filteredFreelancer);
      this.setState({ searchLists: filteredFreelancer, checked: true });
    } else {
      setTimeout(() => {
        this.setState({
          searchLists: this.state.searchLists,
          checked: false
        });
      }, 10000);
    }
  };

  render() {
    console.log("rendered");
    const mapped = this.state.searchLists.map(item => {
      return (
        <div key={item.id}>
          <li>
            {item.name}
            {item.type}
          </li>
        </div>
      );
    });
    return (
      <div className="searchContainer">
        <form>
          <label htmlFor="myInput">All</label>
          <input
            id="myInput"
            type="checkbox"
            onClick={this.handleAll}
            checked={this.state.checked}
          />
          <label htmlFor="myInput">FullTime</label>
          <input id="myInput" type="checkbox" onClick={this.handleFullTime} />
          <label htmlFor="myInput">PartTime</label>
          <input id="myInput" type="checkbox" onClick={this.handlePartTime} />
          <label htmlFor="myInput">Freelancer</label>
          <input id="myInput" type="checkbox" onClick={this.handleFreelancer} />
        </form>
        <ul style={{ marginLeft: "70px" }}>{mapped}</ul>
      </div>
    );
  }
}

export default Search;


这是我的代码 link https://codesandbox.io/s/eloquent-brattain-orv76?file=/src/Search.js

不要用过滤后的结果覆盖您的州。截至目前,每次单击复选框时,您的搜索结果都会被替换为过滤数组。我会将过滤器 属性 添加到您的状态以保存当前选择的过滤器并在渲染期间使用它。

我建议重构您的代码以简化逻辑并消除超时,这会使您的应用看起来没有响应。

this.state ={
  filter: 'none',
  searchList: [...]
}

//unify all checkboxes to share logic, e holds information about event that triggered this function, we will add value to each checkbox for easy access
handleCheckbox = e => {
  if (this.state.filter === e.target.value) this.setState({ filter: "none" });
  else this.setState({ filter: e.target.value, checked: true });
};

//mapped variable will handle filtering results, if `state.filter` matches `item.type` item will be rendered, also if filter is set to none, all items are rendered, this will not preserve multiple filters though,
const mapped = const mapped = this.state.searchLists.map(item => {
      if (item.type === this.state.filter || this.state.filter === "none")
        return (...)

//lastly change inputs to pass filters
  <input
    id="myInput"
    value="PartTime"
    type="checkbox"
    onClick={this.handleCheckbox}
  />

检查这是否按预期工作: https://codesandbox.io/s/vibrant-meadow-9k8u7?file=/src/Search.js:1968-2111

选中的状态无效。我们应该将它存储为一个数组,push/pop 来自它的 checked/unchecked 个项目。

https://codesandbox.io/s/upbeat-ramanujan-b2jui

import React from "react";
import "./Search.css";

class Search extends React.Component {
  constructor() {
    super();
    this.state = {
      filterList: [
        {
          id: 11,
          name: "Part Time",
          value: "PART_TIME"
        },
        {
          id: 12,
          name: "Full Time",
          value: "FULL_TIME"
        },
        {
          id: 13,
          name: "Freelancer",
          value: "FREELANCER"
        }
      ],
      searchLists: [
        {
          id: 1,
          type: "PART_TIME",
          name: "Akash",
          location: "bangalore",
          experience: 1
        },
        {
          id: 2,
          type: "PART_TIME",
          name: "feroz",
          location: "mumbai",
          experience: 3
        },
        {
          id: 3,
          type: "FULL_TIME",
          name: "Farheen",
          location: "agra",
          experience: 5
        },
        {
          id: 4,
          type: "FREELANCER",
          name: "Raju",
          location: "chennai",
          experience: 6
        },
        {
          id: 5,
          type: "FULL_TIME",
          name: "Asif",
          location: "vegas",
          experience: 7
        }
      ],
      activeFilter: []
    };
  }

  onFilterChange(filter) {
    const { filterList, activeFilter } = this.state;
    if (filter === "ALL") {
      if (activeFilter.length === filterList.length) {
        this.setState({ activeFilter: [] });
      } else {
        this.setState({ activeFilter: filterList.map(filter => filter.value) });
      }
    } else {
      if (activeFilter.includes(filter)) {
        const filterIndex = activeFilter.indexOf(filter);
        const newFilter = [...activeFilter];
        newFilter.splice(filterIndex, 1);
        this.setState({ activeFilter: newFilter });
      } else {
        this.setState({ activeFilter: [...activeFilter, filter] });
      }
    }
  }

  render() {
    const { filterList, activeFilter } = this.state;
    let filteredList;
    if (
      activeFilter.length === 0 ||
      activeFilter.length === filterList.length
    ) {
      filteredList = this.state.searchLists;
    } else {
      filteredList = this.state.searchLists.filter(item =>
        this.state.activeFilter.includes(item.type)
      );
    }
    return (
      <div className="searchContainer">
        <form>
          <label htmlFor="myInput">All</label>
          <input
            id="myInput"
            type="checkbox"
            onClick={() => this.onFilterChange("ALL")}
            checked={activeFilter.length === filterList.length}
          />
          {this.state.filterList.map(filter => (
            <React.Fragment>
              <label htmlFor={filter.id}>{filter.name}</label>
              <input
                id={filter.id}
                type="checkbox"
                checked={activeFilter.includes(filter.value)}
                onClick={() => this.onFilterChange(filter.value)}
              />
            </React.Fragment>
          ))}
        </form>
        <ul style={{ marginLeft: "70px" }}>
          {filteredList.map(item => (
            <div key={item.id}>
              <li>
                {item.name} -- {item.type}
              </li>
            </div>
          ))}
        </ul>
      </div>
    );
  }
}

export default Search;

在这里,我为我的复选框项目使用了美食。以下代码片段给出了复选框过滤的逻辑。 handleCuisineChange 是包含逻辑的函数。 for 循环的长度是 8,因为我在这里选择的菜系数量(复选框项目的数量)是 8。用你的复选框数据替换这里的 cuisines。应用此逻辑,您的复选框项目就可以进行过滤了。

axios里面我使用了自己的后端API和端口号。

handleCuisineChange=(cuisine_id)=>
    {
        const {cuisineArray}=this.state; //an empty array declared in constructor
       
        if (cuisineArray.indexOf(cuisine_id) == -1)
        {
            cuisineArray.push(cuisine_id);
        }
        else
        {
            var index=cuisineArray.indexOf(cuisine_id);
            cuisineArray.splice(index,1);
        }    

        const {cuisineArray2}=this.state; //an empty array declared in constructor
        let i=0;
        for (i=0;i<8;i++)
        {
            if(cuisineArray[i]==undefined)
            {
                cuisineArray2[i]=cuisineArray[0];
            }
            else
            {
                cuisineArray2[i]=cuisineArray[i];
            }
        }

        this.props.history.push(`/checking3?cuisine_id1=${cuisineArray2[0]}&cuisine_id2=${cuisineArray2[1]}&cuisine_id3=${cuisineArray2[2]}&cuisine_id4=${cuisineArray2[3]}&cuisine_id5=${cuisineArray2[4]}&cuisine_id6=${cuisineArray2[5]}&cuisine_id7=${cuisineArray2[6]}&cuisine_id8=${cuisineArray2[7]}`);
        let filterObj={cuisine_id1:cuisineArray2[0],cuisine_id2:cuisineArray2[1],cuisine_id3:cuisineArray2[2],cuisine_id4:cuisineArray2[3],cuisine_id5:cuisineArray2[4],cuisine_id6:cuisineArray2[5],cuisine_id7:cuisineArray2[6],cuisine_id8:cuisineArray2[7]};
        axios(
            {
                method:'POST',
                url:`http://localhost:7000/getCuisine`,
                headers:{'Content-Type':'application/json'},
                data:filterObj
            }
        )
        .then(res=>
            {
                this.setState({restaurants:res.data.restaurants});
            })
        .catch(err=>console.log(err))
    }

render()
    {
        const {restaurants}=this.state;
        return(
            
                <div>
                   
                            <input type="checkbox" name="cuisines" id={"1"} onChange={(event) => this.handleCuisineChange("1")}  />
                            <span className="checkbox-items" > North Indian </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines"  id={"2"} onChange={(event) => this.handleCuisineChange("2")}  />
                            <span className="checkbox-items" > south indian </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines" id={"3"} onChange={(event) => this.handleCuisineChange("3")}  />
                            <span className="checkbox-items" > chinese </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines" id={"4"} onChange={(event) => this.handleCuisineChange("1")}  />
                            <span className="checkbox-items" > fast food </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines" id={"5"} onChange={(event) => this.handleCuisineChange("1")}  />
                            <span className="checkbox-items" > Street food </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines" id={"6"} onChange={(event) => this.handleCuisineChange("1")}  />
                            <span className="checkbox-items" > American </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines" id={"7"} onChange={(event) => this.handleCuisineChange("1")}  />
                            <span className="checkbox-items" > Italian </span> <div style={{display: "block"}}> </div>
                            <input type="checkbox" name="cuisines" id={"8"} onChange={(event) => this.handleCuisineChange("1")}  />
                            <span className="checkbox-items" > Mexican </span> <div style={{display: "block"}}> </div>
                </div>
       )
  } //render end