【问题标题】:React dropdown issue反应下拉问题
【发布时间】:2021-10-04 18:17:39
【问题描述】:

我有一个下拉组件和来自 Firebase 的数据,我需要过滤掉它们。第一次,选择有效,但第二次我得到一个空状态,不能全选或做出新的选择。 提前非常感谢。

具有数据库引用和过滤功能的主要组件:

import React, { useEffect, useState } from "react";
import firebase from "../firebase";
import Categories from "./Categories";

const TourMenu = () => {
const [tours, setTours] = useState([]);

useEffect(() => {
  const dbRef = firebase.database().ref();

  dbRef.on("value", (snapshot) => {
    const data = snapshot.val();
    const newToursArray = [];

  for (let inventoryName in data) {
    const toursObject = {
      id: inventoryName,
      name: data[inventoryName].name,
      category: data[inventoryName].category,
      seats: data[inventoryName].seats,
      date: data[inventoryName].date,
    };
    newToursArray.push(toursObject);
   }
   setTours(newToursArray);
  });
}, []);

 const filterItemsCat = (category) => {
    if (category === "all") {
      setTours(tours);
      return;
    }
    const newItems = tours.filter((item) => item.category === category);
    setTours(newItems);

  };

  return (
  <div>
  <h1>Hello from tour menu</h1>

  <Categories filterItemsCat={filterItemsCat} />

  {tours
    .sort((a, b) => a.date > b.date)
    .map((x) => {
      return (
        <div
          key={x.id}
          style={{
            border: "solid 1px",
            bordercolor: "grey",
            width: "230px",
            margin: "10px auto",
          }}
        >
          <p>{x.name}</p>
          <p>{x.category}</p>
          <p>date: {x.date}</p>
          <p>seats: {x.seats}</p>
        </div>
      );
    })}

  <h2>{tours.length === 0 && "hold on ..."}</h2>
</div>
  );
};

export default TourMenu;

这里是下拉组件(类别暂时硬编码):

import React from "react";

function Categories({ categories, filterItemsCat }) {
 
  return (
    <div className="categories-container wrapper">
      <div className="btn-container">
        <select onChange={(e) => filterItemsCat(e.target.value)}>
          <option value="">--Please choose category--</option>
          <option value="all">--CHOOSE ALL--</option>
          <option value="land">land</option>
          <option value="water">water</option>
        </select>
      </div>
    </div>
  );
}

export default Categories;

【问题讨论】:

标签: reactjs firebase filter dropdown


【解决方案1】:

这里是关于过滤数据的事情 - 您需要保持所有数据完好无损,以便您可以继续过滤它。你的 useEffect() 只运行一次来​​获取数据,因为它的依赖数组是空的(don't do this),并且一旦你过滤它就替换你在状态中的数据(通过调用 setTours(newItems)。现在你已经有了状态是一种数据类别 - 当您通过在组件状态中替换其他类别来“删除”其他类别时,您现在将如何过滤其他类别?尝试将当前选择的类别存储在状态中,然后像这样导出显示的游览而是:

import React, { useEffect, useState } from "react";
import firebase from "../firebase";
import Categories from "./Categories";

const TourMenu = () => {
const [tours, setTours] = useState([]);
const [category, setCategory] = useState("all");

useEffect(() => /* ... */, []);

// instead of this
// const filterItemsCat = (category) => {
//    if (category === "all") {
//      setTours(tours);
//      return;
//    }
//    const newItems = tours.filter((item) => item.category === category);
//    setTours(newItems);
//  };

// try this
const filteredTours = tours.filter((item) => item.category === category);

return (
  <div>
  <h1>Hello from tour menu</h1>

  // we'll have to change the event handler
  <Categories onChange={(newCategory) => setCategory(newCategory)} />

  {filteredTours
    .sort((a, b) => a.date > b.date)
    .map((x) => {
      return (
        <div
          key={x.id}
          style={{
            border: "solid 1px",
            bordercolor: "grey",
            width: "230px",
            margin: "10px auto",
          }}
        >
          <p>{x.name}</p>
          <p>{x.category}</p>
          <p>date: {x.date}</p>
          <p>seats: {x.seats}</p>
        </div>
      );
    })}

  <h2>{tours.length === 0 && "hold on ..."}</h2>
</div>
  );
}

React 组件只是函数,所以每次有一个具有新状态现实的新渲染(即类别已更改)时,filteredTours 变量都会有你需要的东西!

【讨论】:

    【解决方案2】:

    非常感谢您的宝贵时间和帮助。其实,为了能在选择类别后再次设置状态,我应该也有类别的状态。

        setCategories(newToursArray);
    

    并且必须有两个像这样的过滤功能:

      const filterItemsCat = (category, filterParam) => {
        if (category && category !== "all") {
          setTours(categories.filter((x) => x.category === category));
        } else {
          setTours(categories);
        }
      };
      const filterItemsDate = (filterParam) => {
        setTours(categories.filter((item) => item.date === filterParam));
      };
    

    【讨论】:

      猜你喜欢
      • 2021-10-31
      • 2021-07-12
      • 2018-04-29
      • 2021-08-01
      • 1970-01-01
      • 2022-11-07
      • 2014-05-28
      • 1970-01-01
      • 2023-02-05
      相关资源
      最近更新 更多