【问题标题】:Filter The List Using Multiple CheckBoxes in React Js在 React Js 中使用多个复选框过滤列表
【发布时间】:2020-10-12 03:59:39
【问题描述】:

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

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;


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

【问题讨论】:

    标签: javascript reactjs setstate react-component


    【解决方案1】:

    在这里,我在复选框项目中使用了美食。以下代码 sn-p 给出了复选框过滤的逻辑。 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

    【讨论】:

      【解决方案2】:

      选中状态无效。我们应该将它存储为一个数组并从中推送/弹出选中/未选中的项目。

      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;

      【讨论】:

        【解决方案3】:

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

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

        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

        【讨论】:

          猜你喜欢
          • 2022-01-20
          • 1970-01-01
          • 2021-03-23
          • 2017-03-19
          • 2021-08-18
          • 2015-05-13
          • 2012-06-12
          • 2012-08-20
          • 1970-01-01
          相关资源
          最近更新 更多