lbs91
lbs91

Reputation: 173

Can't render list of object between two dates in React

I try to render list of concerts between two dates. Problem is that user need to first select desired dates on the page before whole filtering function can run. There is only one useEffect inside the component and I can't filter there because start date and end date are required to this to work. So I moved my filtering function outside the useEffect and now i am getting infinite loop. How to solve that problem in best and professional way ?

import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";

const Explore = () => {
  //Raw JSON Date example:  "2023-02-08T23:15:30.000Z"
  let currentDate = new Date().toJSON().slice(0, 10);

  const [concerts, setConcerts] = useState([]);
  const [startDate, setStartDate] = useState(currentDate);
  const [endDate, setEndDate] = useState(currentDate);
  const [limit, setLimit] = useState(25);

  useEffect(() => {
    const loadConcerts = async () => {
      const request = await axios.get("data/concerts");
      setConcerts(request.data);
    };
    loadConcerts();
  }, []);

  const filtered = concerts.filter((concert) => {
    return concert.datum >= startDate && concert.datum <= endDate;
  });

  setConcerts(filtered);

  if (!filtered.length) {
    return <h1>Loading</h1>;
  }

  return (
    <div>
      <label for="start">Start date:</label>
      <label for="end">End date:</label>

      <input
        type="date"
        id="start"
        value={startDate}
        min="2023-01-01"
        max="2030-12-31"
        onChange={(event) => setStartDate(event.target.value)}
      />

      <input
        type="date"
        id="end"
        value={endDate}
        min="2023-01-01"
        max="2030-12-31"
        onChange={(event) => setEndDate(event.target.value)}
      />

      <div>
        */ <Rendering concert cards> */
      </div>
    </div>
  );
};

export default Explore;

Upvotes: 0

Views: 37

Answers (1)

Kaneki21
Kaneki21

Reputation: 1422

You can have another useEffect triggered when the startDate or endDate gets changed

import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";

const Explore = () => {
  //Raw JSON Date example:  "2023-02-08T23:15:30.000Z"
  let currentDate = new Date().toJSON().slice(0, 10);

  const [concerts, setConcerts] = useState([]);
  const [startDate, setStartDate] = useState(currentDate);
  const [endDate, setEndDate] = useState(currentDate);
  const [limit, setLimit] = useState(25);

  useEffect(() => {
    const loadConcerts = async () => {
      const request = await axios.get("data/concerts");
      setConcerts(request.data);
    };
    loadConcerts();
  }, []);
  useEffect(()=>{
    const filtered = concerts.filter((concert) => {
        return concert.datum >= startDate && concert.datum <= endDate;
      });
    
      setConcerts(filtered);
  },[startDate,endDate])
  

  if (!filtered.length) {
    return <h1>Loading</h1>;
  }

  return (
    <div>
      <label for="start">Start date:</label>
      <label for="end">End date:</label>

      <input
        type="date"
        id="start"
        value={startDate}
        min="2023-01-01"
        max="2030-12-31"
        onChange={(event) => setStartDate(event.target.value)}
      />

      <input
        type="date"
        id="end"
        value={endDate}
        min="2023-01-01"
        max="2030-12-31"
        onChange={(event) => setEndDate(event.target.value)}
      />

      <div>
        */ <Rendering concert cards> */
      </div>
    </div>
  );
};

export default Explore;

Upvotes: 1

Related Questions