0

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;
1
  • 1
    You can simply use filtered to render your items. No need to setConcerts with the filtered value Commented Feb 11, 2023 at 10:43

1 Answer 1

1

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;
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks looks like it solved my question. I just have another problem but its for another topic.
sure, since keep useEffect runs at the intiial render so keep a note of that until user selects proper date range..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.