reactjs - 应用多个动态过滤器

经过整整两天的反复试验和谷歌搜索,我开始失去理智,真的需要一些帮助。这是我的第二个 React 爱好项目,所以如果它包含任何“不可行的”,请多多包涵。

情况: 我调用一个 API,将数据存储在状态(酒店房间)中,首先显示所有房间。应用搜索后,我想进一步缩小搜索范围 - 这很有效(使用硬编码值进行测试)。 我获取所有可用房间,过滤它们,将它们存储到另一个数组中,然后显示该数组。

问题: 我的搜索不是动态的。我可以缩小结果范围,但不能“恢复”。例如:如果用户希望按价格和“允许携带宠物”缩小房间范围,则会显示出来。但是,如果他决定带宠物没那么重要并取消选中筛选器,结果将与以前相同。 handleClicks 和 Buttons 只是用来快速测试的,它们与最终结果无关。另外,我省略了 fetchRoomsData(),因为它在这里并不重要。

如果有人能帮我解决这个问题,我将不胜感激! 提前致谢:)

import React, { Component } from "react";
import Roomcard from "./RoomCard.js";

export default class AllRooms extends Component {
  constructor() {
    super();
    this.state = {
      data: undefined,
      fetched: false,
      roomsToDisplay: [],
      hasFilter: {
        price: 300,
        capacity: 3,
        pets: true,
        breakfast: false,
      },
    };
  }

  componentDidMount() {
    this.fetchRoomsData();
  }

  handleClick1() {
    this.filterByPrice();
  }

  handleClick2() {
    this.filterByPets();
  }

  handleClick3() {
    this.filterByCapacity();
  }

  handleClick4() {
    this.filterByBreakfast();
  }

  handleClick5() {
    this.generateAllRooms();
  }

  filterByPrice() {
    let tempArr = [];
    this.state.roomsToDisplay.map((room) =>
      room.props.price < this.state.hasFilter.price ? tempArr.push(room) : null
    );
    if (tempArr.length > 0) {
      this.setState({ roomsToDisplay: tempArr });
    } else {
      this.setState({
        roomsToDisplay: <h1>There are no matching results.</h1>,
      });
    }
  }

  filterByPets() {
    let tempArr = [];
    this.state.roomsToDisplay.map((room) =>
      room.props.pets ? tempArr.push(room) : null
    );
    if (tempArr.length > 0) {
      this.setState({ roomsToDisplay: tempArr });
    } else {
      this.setState({
        roomsToDisplay: <h1>There are no matching results.</h1>,
      });
    }
  }

  filterByBreakfast() {
    let tempArr = [];
    this.state.roomsToDisplay.map((room) =>
      room.props.breakfast ? tempArr.push(room) : null
    );
    if (tempArr.length > 0) {
      this.setState({ roomsToDisplay: tempArr });
    } else {
      this.setState({
        roomsToDisplay: <h1>There are no matching results.</h1>,
      });
    }
  }

  filterByCapacity() {
    let tempArr = [];
    this.state.roomsToDisplay.map((room) =>
      room.props.capacity > this.state.hasFilter.capacity
        ? tempArr.push(room)
        : null
    );
    if (tempArr.length > 0) {
      this.setState({ roomsToDisplay: tempArr });
    } else {
      this.setState({
        roomsToDisplay: <h1>There are no matching results.</h1>,
      });
    }
  }

 

  generateAllRooms() {
    let finalDiv = [];

    this.state.data.items.map((room) =>
      finalDiv.push(
        <Roomcard
          price={room.fields.price}
          titleImage={`https:${room.fields.images[0].fields.file.url}`}
          allImages={room.fields.images.map((image) => image.fields.file.url)}
          name={room.fields.name.toUpperCase()}
          slug={room.fields.slug}
          capacity={room.fields.capacity}
          type={room.fields.type}
          size={room.fields.size}
          pets={room.fields.pets}
          breakfast={room.fields.breakfast}
          featured={room.fields.featured}
          description={room.fields.description}
          extras={room.fields.extras}
          key={Math.random() * 1000}
        />
      )
    );
    this.setState({ roomsToDisplay: finalDiv });
  }

  render() {
    return (
      <>
        <div className="search-field-outer-box">
       

          <button onClick={() => this.handleClick1()}> Filter By Price </button>
          <button onClick={() => this.handleClick2()}> Filter By Pets </button>
          <button onClick={() => this.handleClick3()}> Filter By capacity </button>
          <button onClick={() => this.handleClick4()}> Filter By breakfast </button>
          <button onClick={() => this.handleClick5()}> Reset Filter </button>
        </div>

        {this.state.data ? (
          <div className="room-card-container">{this.state.roomsToDisplay}</div>
        ) : undefined}
      </>
    );
  }
}

最佳答案

? 欢迎来到 SO

首先,不要在状态中存储 jsx 元素,更喜欢只存储值并在渲染时创建 jsx。

现在,我要做的是将整个数据集放在一个状态变量中(并且从不修改它),另一个用于过滤后的数据

this.state = {
  data:[],
  filteredData:[]
};

// Here at some point when retrieving the data, 
// this.setState({data: fetchedData, filteredData: fetchedData});

filterByBreakfast() {
  const dataFiltered = // your code to filter
  this.setState({
    filterdData: dataFiltered,
  });
}

resetFilters() {
  // Reset the Filtered Data
  this.setState({
    filterdData: this.state.data,
  });
}

render() {
  return {
    <div>
      <div>
        <button onClick={this.filterByBreakfast}> Filter By breakfast </button>
        <button onClick={this.resetFilters}> Reset Filter </button>
      </div>
      <div>
        {filteredData.length > 0 ? filteredData.map(item => <div>{item}</div>) : <div>No results</div>}
      </div>
    </div>
  }
}

https://stackoverflow.com/questions/62581358/

相关文章:

android - 使用 Moshi 处理错误响应

javascript - 如何使用 React 在客户端裁剪图像而不丢失分辨率

javascript - Angular ngrx : TypeError: Cannot free

python - DBSCAN 聚类甚至无法处理 40k 数据,但可以使用 python 和 skl

ios - UIView 作为@EnvironmentObject 的订阅者

java - SonarQube Scanner - 插件下载之间的长时间停顿

vue.js - 当对象没有(可识别的)变化时触发 Vue 监视

rust - 我如何使字符串比闭包体生命周期更长?

java - 将内部 HashMap 类型强制转换为 Map

r - 在 Windows 上安装 odbc R 包时出现问题