Reputation: 173
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
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