用React过滤无法正常工作

发布于 2025-01-31 03:11:08 字数 8355 浏览 0 评论 0原文

每当我的3个过滤器中的任何一个都更改时,我都在尝试过滤一系列汽车。我认为合适的方式 - 对于瞬间的瞬间 - 每当任何一个更改时,请检查所有过滤器,按以下顺序:handle onchangeDateFilter(如果未设置此过滤器,我将所有汽车都设置为初始状态),thangeonchangefuelfter, hangeonchangeseats。我显示了一些console.log s,但出于某种原因(我认为它可能与渲染相关,并且 使用使用。或在依赖项数组中的任何值更改后,对吗?)(PS:我知道我可以以某种方式通过以某种方式捕获Prevstate,以某种方式检查新值与旧值,以便我不运行一个没有理由再次过滤器,但是忘记了如何捕获Prevstate,因为它也应该可以正常工作,因为现在也应该很好地捕获Prevstate),

因此,任何想法以下代码为什么不起作用?

import moment from "moment";
import { Link } from "react-router-dom";
import Spinner from "../components/Spinner";
import { Col, Row, DatePicker, Select } from "antd";
import React, { useState, useEffect, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import DefaultLayout from "../components/DefaultLayout";
import { getAllCars } from "../redux/actions/carsActions";
import cron from "node-cron";

const { RangePicker } = DatePicker;

function Home() {
  
  const { cars } = useSelector((state) => state.carsReducer); // state aici e de fapt store-ul nostru!

  const [timeRange, setTimeRange] = useState([]);
  const [fuelTypes, setFuelTypes] = useState([]);
  const [seatNumbers, setSeatNumbers] = useState([]);

  const { loading } = useSelector((state) => state.alertsReducer);
  const [totalCars, setTotalcars] = useState([]);
  const dispatch = useDispatch();

  useEffect(() => {
    console.log("merge!");
    dispatch(getAllCars());
  }, []);

  useEffect(() => {
    console.log("cars bro", cars);
    setFuelTypes(
      [...new Set(cars.map((car) => car.fuelType.toLowerCase()))].sort()
    );

    setSeatNumbers(
      [...new Set(cars.map((car) => car.capacity))].sort((a, b) => a - b)
    );

    setTotalcars(cars);
  }, [cars]);

  useEffect(() => {
    console.log("refilter is triggered!");
    refilter();
  }, [timeRange, fuelTypes, seatNumbers]);


  function handleOnChangeDateFilter() {


    console.log("intra in handleOnChangeDateFilter", timeRange);
    console.log("totalCars:", totalCars);
    if (timeRange.length === 0) {
      console.log(
        "No date range filter specified!  Will reinitialize and then proceed with other filters!"
      );
      setTotalcars(cars);
      return;
    }
    var selectedFrom = moment(timeRange[0], "MMM DD yyyy HH:mm");
    var selectedTo = moment(timeRange[1], "MMM DD yyyy HH:mm");
    console.log("selectedFrom", selectedFrom, "selectedTo", selectedTo);

    var temp = [];

    for (var car of cars) {
      if (car.bookedTimeSlots.length === 0) {
        temp.push(car);
      } else {
        var toAdd = true;
        for (var booking of car.bookedTimeSlots) {
          if (
            selectedFrom.isBetween(booking.from, booking.to) ||
            selectedTo.isBetween(booking.from, booking.to) ||
            moment(booking.from).isBetween(selectedFrom, selectedTo) ||
            moment(booking.to).isBetween(selectedFrom, selectedTo)
          ) {
            console.log(
              `${car.name} is booked from ${booking.from} to ${booking.to}! Will NOT be added!`
            );
            toAdd = false;
            break; // we should not add this car to the displayed cars if we found a minimum of one booking that
            // intersects non-available time range
          }
        }
        if (toAdd) temp.push(car);
      }
    }

    setTotalcars(temp);
  }

  function handleOnChangeFuelFilter() {
    console.log(`intra in handleOnChangeFuelFilter:`, totalCars);
    if (fuelTypes === []) {
      console.log("no fuel filter specified! Will leave function!");
      return;
    }
    var temp = [];
    for (var car of totalCars) {
      if (fuelTypes.includes(car.fuelType.toLowerCase())) {
        // console.log(`${car.name} is of type ${car.fuelType}! Will be added!`);
        temp.push(car);
      }
    }
    setTotalcars(temp);
  }

  function handleOnChangeSeatsFilter() {
    console.log(`intra in handleOnChangeSeatsFilter:`, totalCars);
    if (seatNumbers === []) {
      console.log("No seat filter specified! Will leave function!");
      return;
    }
    var temp = [];
    for (var car of totalCars) {
      if (seatNumbers.includes(car.capacity)) {
        // console.log(`${car.name} has ${car.capacity}! Will be added!`);
        temp.push(car);
      }
    }
    setTotalcars(temp);
  }

  function onRangePickerFilterChange(values) {
    console.log("============STARTED============");
    console.log("onRangePickerFilterChange ->", values);
    setTimeRange(values);
  }

  function onSeatsFilterChange(values) {
    console.log("============STARTED============");
    console.log("onSeatsFilterChange ->", values);
    setSeatNumbers(values);
  }

  function onFuelFilterChange(values) {
    console.log("============STARTED============");
    console.log("onFuelFilterChange ->", values);
    setFuelTypes(values);
  }

  function refilter() {
    // console.log('values refilter:', values);
    // console.log('============STARTED============');
    handleOnChangeDateFilter();
    console.log("AFTER DATE FILTER:", totalCars);
    handleOnChangeFuelFilter();
    console.log("AFTER FUEL FILTER:", totalCars);
    handleOnChangeSeatsFilter();
    console.log("AFTER SEATS FILTER(final):", totalCars);
    console.log("============FINISHED============");
  }

  return (
    <DefaultLayout>
      <Row className="mt-3" justify="center">
        <Col lg={20} sm={24} className="d-flex justify-content-left">
          <RangePicker
            // ref={refRangePicker}
            showTime={{ format: "HH:mm" }}
            format="MMM DD yyyy HH:mm"
            // onChange={handleOnChangeDateFilter}
            // onChange={refilter}
            onChange={onRangePickerFilterChange}
          />
          <Select
            // onChange={handleFuelFilterChange}
            // onChange={refilter}
            onChange={onFuelFilterChange}
            allowClear
            mode="multiple"
            placeholder="Fuel type"
            style={{ width: "10%" }}
          >
            {fuelTypes.map((fuelType, index) => {
              return (
                <Select.Option key={index} value={fuelType}>
                  {fuelType}
                </Select.Option>
              );
            })}
          </Select>
          <Select
            // onChange={refilter}
            onChange={onSeatsFilterChange}
            allowClear
            mode="multiple"
            placeholder="Seats"
            style={{ width: "10%" }}
          >
            {seatNumbers.map((seatNumber, index) => {
              return (
                <Select.Option key={index} value={seatNumber}>
                  {seatNumber}
                </Select.Option>
              );
            })}
          </Select>
        </Col>
      </Row>

      {loading === true && <Spinner />}

      <Row justify="center" gutter={16}>
        {totalCars.map((car) => {
          return (
            <Col lg={5} sm={24} xs={24}>
              <div className="car p-1 bs1">
                <img src={car.image} className="carimg" />

                <div className="car-content d-flex align-items-center justify-content-between">
                  <div className="text-left pl-2">
                    <p>{car.name}</p>
                    <p>
                      <sup>{car.rentPerHour} eur</sup>/<sub>Hour</sub>
                    </p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Seats: {car.capacity}</p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Fuel: {car.fuelType}</p>
                  </div>

                  <div>
                    <button className="btn1 mr-2">
                      <Link to={`/booking/${car._id}`}>Book Now</Link>
                    </button>
                  </div>
                </div>
              </div>
            </Col>
          );
        })}
      </Row>
    </DefaultLayout>
  );
}

export default Home;

I am trying to filter an array of cars whenever any of my 3 filters changes. The way I see fit -for the moment- with React is to: check all filters whenever any of them changes, in this order: handleOnChangeDateFilter (where I set all my cars to the initial state if this filter is not set), handleOnChangeFuelFilter, handleOnChangeSeats. I displayed some console.logs but for some reason (I think it might be something related to rendering and when useEffect runs. It runs after every re-render OR after any of the values in the dependency array changes, right?) (PS: I know I could somehow check to compare the new values with the old values by somehow capturing the prevState, so that I do not run a specific filter again with no reason, but forgot how to capture prevState. Will do that later, as it should work fine without that now, too)

So, any idea why the below code does not work?

import moment from "moment";
import { Link } from "react-router-dom";
import Spinner from "../components/Spinner";
import { Col, Row, DatePicker, Select } from "antd";
import React, { useState, useEffect, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import DefaultLayout from "../components/DefaultLayout";
import { getAllCars } from "../redux/actions/carsActions";
import cron from "node-cron";

const { RangePicker } = DatePicker;

function Home() {
  
  const { cars } = useSelector((state) => state.carsReducer); // state aici e de fapt store-ul nostru!

  const [timeRange, setTimeRange] = useState([]);
  const [fuelTypes, setFuelTypes] = useState([]);
  const [seatNumbers, setSeatNumbers] = useState([]);

  const { loading } = useSelector((state) => state.alertsReducer);
  const [totalCars, setTotalcars] = useState([]);
  const dispatch = useDispatch();

  useEffect(() => {
    console.log("merge!");
    dispatch(getAllCars());
  }, []);

  useEffect(() => {
    console.log("cars bro", cars);
    setFuelTypes(
      [...new Set(cars.map((car) => car.fuelType.toLowerCase()))].sort()
    );

    setSeatNumbers(
      [...new Set(cars.map((car) => car.capacity))].sort((a, b) => a - b)
    );

    setTotalcars(cars);
  }, [cars]);

  useEffect(() => {
    console.log("refilter is triggered!");
    refilter();
  }, [timeRange, fuelTypes, seatNumbers]);


  function handleOnChangeDateFilter() {


    console.log("intra in handleOnChangeDateFilter", timeRange);
    console.log("totalCars:", totalCars);
    if (timeRange.length === 0) {
      console.log(
        "No date range filter specified!  Will reinitialize and then proceed with other filters!"
      );
      setTotalcars(cars);
      return;
    }
    var selectedFrom = moment(timeRange[0], "MMM DD yyyy HH:mm");
    var selectedTo = moment(timeRange[1], "MMM DD yyyy HH:mm");
    console.log("selectedFrom", selectedFrom, "selectedTo", selectedTo);

    var temp = [];

    for (var car of cars) {
      if (car.bookedTimeSlots.length === 0) {
        temp.push(car);
      } else {
        var toAdd = true;
        for (var booking of car.bookedTimeSlots) {
          if (
            selectedFrom.isBetween(booking.from, booking.to) ||
            selectedTo.isBetween(booking.from, booking.to) ||
            moment(booking.from).isBetween(selectedFrom, selectedTo) ||
            moment(booking.to).isBetween(selectedFrom, selectedTo)
          ) {
            console.log(
              `${car.name} is booked from ${booking.from} to ${booking.to}! Will NOT be added!`
            );
            toAdd = false;
            break; // we should not add this car to the displayed cars if we found a minimum of one booking that
            // intersects non-available time range
          }
        }
        if (toAdd) temp.push(car);
      }
    }

    setTotalcars(temp);
  }

  function handleOnChangeFuelFilter() {
    console.log(`intra in handleOnChangeFuelFilter:`, totalCars);
    if (fuelTypes === []) {
      console.log("no fuel filter specified! Will leave function!");
      return;
    }
    var temp = [];
    for (var car of totalCars) {
      if (fuelTypes.includes(car.fuelType.toLowerCase())) {
        // console.log(`${car.name} is of type ${car.fuelType}! Will be added!`);
        temp.push(car);
      }
    }
    setTotalcars(temp);
  }

  function handleOnChangeSeatsFilter() {
    console.log(`intra in handleOnChangeSeatsFilter:`, totalCars);
    if (seatNumbers === []) {
      console.log("No seat filter specified! Will leave function!");
      return;
    }
    var temp = [];
    for (var car of totalCars) {
      if (seatNumbers.includes(car.capacity)) {
        // console.log(`${car.name} has ${car.capacity}! Will be added!`);
        temp.push(car);
      }
    }
    setTotalcars(temp);
  }

  function onRangePickerFilterChange(values) {
    console.log("============STARTED============");
    console.log("onRangePickerFilterChange ->", values);
    setTimeRange(values);
  }

  function onSeatsFilterChange(values) {
    console.log("============STARTED============");
    console.log("onSeatsFilterChange ->", values);
    setSeatNumbers(values);
  }

  function onFuelFilterChange(values) {
    console.log("============STARTED============");
    console.log("onFuelFilterChange ->", values);
    setFuelTypes(values);
  }

  function refilter() {
    // console.log('values refilter:', values);
    // console.log('============STARTED============');
    handleOnChangeDateFilter();
    console.log("AFTER DATE FILTER:", totalCars);
    handleOnChangeFuelFilter();
    console.log("AFTER FUEL FILTER:", totalCars);
    handleOnChangeSeatsFilter();
    console.log("AFTER SEATS FILTER(final):", totalCars);
    console.log("============FINISHED============");
  }

  return (
    <DefaultLayout>
      <Row className="mt-3" justify="center">
        <Col lg={20} sm={24} className="d-flex justify-content-left">
          <RangePicker
            // ref={refRangePicker}
            showTime={{ format: "HH:mm" }}
            format="MMM DD yyyy HH:mm"
            // onChange={handleOnChangeDateFilter}
            // onChange={refilter}
            onChange={onRangePickerFilterChange}
          />
          <Select
            // onChange={handleFuelFilterChange}
            // onChange={refilter}
            onChange={onFuelFilterChange}
            allowClear
            mode="multiple"
            placeholder="Fuel type"
            style={{ width: "10%" }}
          >
            {fuelTypes.map((fuelType, index) => {
              return (
                <Select.Option key={index} value={fuelType}>
                  {fuelType}
                </Select.Option>
              );
            })}
          </Select>
          <Select
            // onChange={refilter}
            onChange={onSeatsFilterChange}
            allowClear
            mode="multiple"
            placeholder="Seats"
            style={{ width: "10%" }}
          >
            {seatNumbers.map((seatNumber, index) => {
              return (
                <Select.Option key={index} value={seatNumber}>
                  {seatNumber}
                </Select.Option>
              );
            })}
          </Select>
        </Col>
      </Row>

      {loading === true && <Spinner />}

      <Row justify="center" gutter={16}>
        {totalCars.map((car) => {
          return (
            <Col lg={5} sm={24} xs={24}>
              <div className="car p-1 bs1">
                <img src={car.image} className="carimg" />

                <div className="car-content d-flex align-items-center justify-content-between">
                  <div className="text-left pl-2">
                    <p>{car.name}</p>
                    <p>
                      <sup>{car.rentPerHour} eur</sup>/<sub>Hour</sub>
                    </p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Seats: {car.capacity}</p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Fuel: {car.fuelType}</p>
                  </div>

                  <div>
                    <button className="btn1 mr-2">
                      <Link to={`/booking/${car._id}`}>Book Now</Link>
                    </button>
                  </div>
                </div>
              </div>
            </Col>
          );
        })}
      </Row>
    </DefaultLayout>
  );
}

export default Home;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧夏天 2025-02-07 03:11:08

问题在于过滤逻辑,而不是使用效率或与反应严格相关的其他任何内容。这是完整的工作代码(可以改进,但这是一个工作解决方案):

import moment from "moment";
import { Link } from "react-router-dom";
import Spinner from "../components/Spinner";
import { Col, Row, DatePicker, Select } from "antd";
import React, { useState, useEffect, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import DefaultLayout from "../components/DefaultLayout";
import { getAllCars } from "../redux/actions/carsActions";

const { RangePicker } = DatePicker;

function Home() {
  const { cars } = useSelector((store) => {
    console.log("in callback:", store.carsReducer);
    return store.carsReducer;
  });

  const [timeRange, setTimeRange] = useState([]);
  const [fuelTypes, setFuelTypes] = useState([]); // all present fuel types in my DB (initialized in first useEffect)
  const [seatNumbers, setSeatNumbers] = useState([]); // all present seat capacity numbers in my DB (initialized in first useEffect)

  const [selectedTimeRange, setSelectedTimeRange] = useState([]);
  const [selectedFuelTypes, setSelectedFuelTypes] = useState([]); // selected fuel types (selected by the user from the antd Select.Option component)
  const [selectedSeatNumbers, setSelectedSeatNumbers] = useState([]); // selected seat numbers (selected by the user from the antd Select.Option component)

  const { loading } = useSelector((store) => store.alertsReducer);
  const [totalCars, setTotalCars] = useState([]);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getAllCars());
  }, []);

  useEffect(() => {
    setFuelTypes(
      [...new Set(cars.map((car) => car.fuelType.toLowerCase()))].sort()
    ); // all possible fuel types
    setSeatNumbers(
      [...new Set(cars.map((car) => car.capacity))].sort((a, b) => a - b)
    ); // all possible seat numbers
    setTotalCars(cars); // all cars
  }, [cars]);

  useEffect(() => {
    refilter();
  }, [selectedTimeRange, selectedFuelTypes, selectedSeatNumbers]);

  function refilter() {
    // no need for 3 separate functions (that would mean setting the state of the totalCars variable 3 times
    // using the `setTotalCars` function - which -if I am not mistaken- might trigger unexpected behavior
    // with the re-rendering of the component)
    // temporary array; eventually, totalCars will be assigned `temp` value using the `setTotalCars` method!
    var temp = [];

    // logica timeRange
    if (selectedTimeRange.length === 0) {
      console.log("user selected no time range");
      temp = [...cars];
    } else {
      console.log('user selected timeRange: ', selectedTimeRange);
      var selectedFrom = moment(selectedTimeRange[0], "MMM DD yyyy HH");
      var selectedTo = moment(selectedTimeRange[1], "MMM DD yyyy HH");

      for (var car of cars) {
        if (car.bookedTimeSlots.length == 0) {
          temp.push(car);
        } else {
          var toBeAdded = true;
          for (var booking of car.bookedTimeSlots) {
            if (selectedFrom.isBetween(booking.from, booking.to) ||
                selectedTo.isBetween(booking.from, booking.to) ||
                moment(booking.from).isBetween(selectedFrom, selectedTo) ||
                moment(booking.to).isBetween(selectedFrom, selectedTo)) {
                  toBeAdded = false; // if time range of booking overlaps with selected time range, don't add car to temp!
                  break;
            }
          }
          if (toBeAdded) {
            temp.push(car);
          }
        }
      }
    }

    // fuelTypes logic
    if (selectedFuelTypes.length !== 0){
      console.log('User selected fuel types: ', selectedFuelTypes);
      temp = temp.filter((car) => selectedFuelTypes.includes(car.fuelType));
      console.log(`filtered by fuelTypes: ${temp}`);
    }

    // seatsNumber logic
    if (selectedSeatNumbers.length !== 0){
      console.log('User selected seat numbers: ', selectedSeatNumbers);
      temp = temp.filter((car) => selectedSeatNumbers.includes(car.capacity));
      console.log(`filtered by seatsNumber: ${temp.length}`);
    }

    // finally, assign filtered values to totalCars!
    console.log("temp:", temp);
    setTotalCars(temp);
  }

  return (
    <DefaultLayout>
      <Row className="mt-3" justify="center">
        <Col lg={20} sm={24} className="d-flex justify-content-left">
          <RangePicker
            showTime={{ format: "HH:mm" }}
            format="MMM DD yyyy HH:mm"
            onChange={(values) => {
              setSelectedTimeRange(values);
            }}
          />
          <Select
            allowClear
            mode="multiple"
            placeholder="Fuel"
            style={{ width: "10%" }}
            onChange={(values) => {
              setSelectedFuelTypes(values);
            }}
          >
            {fuelTypes.map((fuelType, index) => {
              return (
                <Select.Option key={index} value={fuelType}>
                  {fuelType}
                </Select.Option>
              );
            })}
          </Select>
          <Select
            onChange={(values) => {
              setSelectedSeatNumbers(values);
            }}
            allowClear
            mode="multiple"
            placeholder="Seats"
            style={{ width: "10%" }}
          >
            {seatNumbers.map((seatNumber, index) => {
              return (
                <Select.Option key={index} value={seatNumber}>
                  {seatNumber}
                </Select.Option>
              );
            })}
          </Select>
        </Col>
      </Row>

      {loading === true && <Spinner />}

      <Row justify="center" gutter={16}>
        {totalCars.map((car) => {
          return (
            <Col lg={5} sm={24} xs={24}>
              <div className="car p-1 bs1">
                <img src={car.image} className="carimg" />

                <div className="car-content d-flex align-items-center justify-content-between">
                  <div className="text-left pl-2">
                    <p>{car.name}</p>
                    <p>
                      <sup>{car.rentPerHour} eur</sup>/<sub>Hour</sub>
                    </p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Seats: {car.capacity}</p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Fuel: {car.fuelType}</p>
                  </div>

                  <div>
                    <button className="btn1 mr-2">
                      <Link to={`/booking/${car._id}`}>Book Now</Link>
                    </button>
                  </div>
                </div>
              </div>
            </Col>
          );
        })}
      </Row>
    </DefaultLayout>
  );
}

export default Home;

The problem was with the filtering logic, not the useEffects or anything else strictly related to React. Here is the full working code (could be improved, but this is a working solution):

import moment from "moment";
import { Link } from "react-router-dom";
import Spinner from "../components/Spinner";
import { Col, Row, DatePicker, Select } from "antd";
import React, { useState, useEffect, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import DefaultLayout from "../components/DefaultLayout";
import { getAllCars } from "../redux/actions/carsActions";

const { RangePicker } = DatePicker;

function Home() {
  const { cars } = useSelector((store) => {
    console.log("in callback:", store.carsReducer);
    return store.carsReducer;
  });

  const [timeRange, setTimeRange] = useState([]);
  const [fuelTypes, setFuelTypes] = useState([]); // all present fuel types in my DB (initialized in first useEffect)
  const [seatNumbers, setSeatNumbers] = useState([]); // all present seat capacity numbers in my DB (initialized in first useEffect)

  const [selectedTimeRange, setSelectedTimeRange] = useState([]);
  const [selectedFuelTypes, setSelectedFuelTypes] = useState([]); // selected fuel types (selected by the user from the antd Select.Option component)
  const [selectedSeatNumbers, setSelectedSeatNumbers] = useState([]); // selected seat numbers (selected by the user from the antd Select.Option component)

  const { loading } = useSelector((store) => store.alertsReducer);
  const [totalCars, setTotalCars] = useState([]);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getAllCars());
  }, []);

  useEffect(() => {
    setFuelTypes(
      [...new Set(cars.map((car) => car.fuelType.toLowerCase()))].sort()
    ); // all possible fuel types
    setSeatNumbers(
      [...new Set(cars.map((car) => car.capacity))].sort((a, b) => a - b)
    ); // all possible seat numbers
    setTotalCars(cars); // all cars
  }, [cars]);

  useEffect(() => {
    refilter();
  }, [selectedTimeRange, selectedFuelTypes, selectedSeatNumbers]);

  function refilter() {
    // no need for 3 separate functions (that would mean setting the state of the totalCars variable 3 times
    // using the `setTotalCars` function - which -if I am not mistaken- might trigger unexpected behavior
    // with the re-rendering of the component)
    // temporary array; eventually, totalCars will be assigned `temp` value using the `setTotalCars` method!
    var temp = [];

    // logica timeRange
    if (selectedTimeRange.length === 0) {
      console.log("user selected no time range");
      temp = [...cars];
    } else {
      console.log('user selected timeRange: ', selectedTimeRange);
      var selectedFrom = moment(selectedTimeRange[0], "MMM DD yyyy HH");
      var selectedTo = moment(selectedTimeRange[1], "MMM DD yyyy HH");

      for (var car of cars) {
        if (car.bookedTimeSlots.length == 0) {
          temp.push(car);
        } else {
          var toBeAdded = true;
          for (var booking of car.bookedTimeSlots) {
            if (selectedFrom.isBetween(booking.from, booking.to) ||
                selectedTo.isBetween(booking.from, booking.to) ||
                moment(booking.from).isBetween(selectedFrom, selectedTo) ||
                moment(booking.to).isBetween(selectedFrom, selectedTo)) {
                  toBeAdded = false; // if time range of booking overlaps with selected time range, don't add car to temp!
                  break;
            }
          }
          if (toBeAdded) {
            temp.push(car);
          }
        }
      }
    }

    // fuelTypes logic
    if (selectedFuelTypes.length !== 0){
      console.log('User selected fuel types: ', selectedFuelTypes);
      temp = temp.filter((car) => selectedFuelTypes.includes(car.fuelType));
      console.log(`filtered by fuelTypes: ${temp}`);
    }

    // seatsNumber logic
    if (selectedSeatNumbers.length !== 0){
      console.log('User selected seat numbers: ', selectedSeatNumbers);
      temp = temp.filter((car) => selectedSeatNumbers.includes(car.capacity));
      console.log(`filtered by seatsNumber: ${temp.length}`);
    }

    // finally, assign filtered values to totalCars!
    console.log("temp:", temp);
    setTotalCars(temp);
  }

  return (
    <DefaultLayout>
      <Row className="mt-3" justify="center">
        <Col lg={20} sm={24} className="d-flex justify-content-left">
          <RangePicker
            showTime={{ format: "HH:mm" }}
            format="MMM DD yyyy HH:mm"
            onChange={(values) => {
              setSelectedTimeRange(values);
            }}
          />
          <Select
            allowClear
            mode="multiple"
            placeholder="Fuel"
            style={{ width: "10%" }}
            onChange={(values) => {
              setSelectedFuelTypes(values);
            }}
          >
            {fuelTypes.map((fuelType, index) => {
              return (
                <Select.Option key={index} value={fuelType}>
                  {fuelType}
                </Select.Option>
              );
            })}
          </Select>
          <Select
            onChange={(values) => {
              setSelectedSeatNumbers(values);
            }}
            allowClear
            mode="multiple"
            placeholder="Seats"
            style={{ width: "10%" }}
          >
            {seatNumbers.map((seatNumber, index) => {
              return (
                <Select.Option key={index} value={seatNumber}>
                  {seatNumber}
                </Select.Option>
              );
            })}
          </Select>
        </Col>
      </Row>

      {loading === true && <Spinner />}

      <Row justify="center" gutter={16}>
        {totalCars.map((car) => {
          return (
            <Col lg={5} sm={24} xs={24}>
              <div className="car p-1 bs1">
                <img src={car.image} className="carimg" />

                <div className="car-content d-flex align-items-center justify-content-between">
                  <div className="text-left pl-2">
                    <p>{car.name}</p>
                    <p>
                      <sup>{car.rentPerHour} eur</sup>/<sub>Hour</sub>
                    </p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Seats: {car.capacity}</p>
                  </div>

                  <div className="text-left pl-2">
                    <p>Fuel: {car.fuelType}</p>
                  </div>

                  <div>
                    <button className="btn1 mr-2">
                      <Link to={`/booking/${car._id}`}>Book Now</Link>
                    </button>
                  </div>
                </div>
              </div>
            </Col>
          );
        })}
      </Row>
    </DefaultLayout>
  );
}

export default Home;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文