I am building a simple agenda component and ran into a problem. The idea is that when a person clicks on the day and then sees trainings from this specific day. My logic is the following
I tried putting function invocation to handleClick function, which did not help. For me it seems that the problem can occur with function not returning the value in time for component to pass it, but I don't know how to bypass this problem. Here is the codesandbox with everything - please help
https://codesandbox.io/s/cranky-johnson-s2dj3?file=/src/scheduledTrainingCard.js
Here is the code to parent component, as the problem is here
import React, { useState } from "react";
import { Transition, Grid, Button, Container } from "semantic-ui-react";
import ScheduledTrainingCard from "./scheduledTrainingCard";
function ScheduleComponent(props) {
const days = [
{
id: "1",
dayTrainings: [
{
time: "20:15:00",
training: "zumba",
trainer: "joe"
},
{
time: "16:00:00",
training: "stretching",
trainer: "lily"
}
],
date:
"Thu Dec 28 1995 00:00:00 GMT+0100 (Central European Standard Time)",
createdAt: "2021-07-14T19:30:59.177Z"
},
{
id: "2",
dayTrainings: [
{
time: "23:15:00",
training: "boxing",
trainer: "phoebe"
},
{
time: "15:00:00",
training: "dancing",
trainer: "kate"
}
],
date: "Thu Sep 23 2021 20:57:38 GMT+0200 (Central European Summer Time)",
createdAt: "2021-09-23T19:01:53.801Z"
},
{
id: "3",
dayTrainings: [
{
time: "23:15:00",
training: "ballet",
trainer: "nataly"
},
{
time: "12:00:00",
training: "crossfit",
trainer: "sheldon"
}
],
date: "Fri Jul 23 2021 21:02:37 GMT+0200 (Central European Summer Time)",
createdAt: "2021-09-23T19:03:31.161Z"
}
];
const [activeItem, setActiveItem] = useState("");
const handleItemClick = (e) => {
setActiveItem(e.target.name);
};
function showSelectedDay(arr, dayId) {
arr.forEach((element, index) => {
if (dayId === element.id) {
console.log("selected day is " + element.date);
let trainings = element.dayTrainings;
trainings.map((training) => {
return training;
});
} else {
console.log("not selected, day id is " + element.id);
}
});
}
const ScheduleComponent = (
<Container style={{ textAlign: "left" }}>
<h1 style={{ textAlign: "center" }}>Training Schedule</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Incidunt
dolor unde repudiandae culpa ullam, asperiores officiis ratione
repellat quaerat nihil vel corporis distinctio vero doloribus dolore
optio commodi voluptatum inventore.
</p>
<Container>
<Grid style={{ margin: "2rem auto", textAlign: "center" }} relaxed>
<Button onClick={(e) => handleItemClick(e)} name={"1"}>
Monday
</Button>
<Button onClick={(e) => handleItemClick(e)} name={"2"}>
Tuesday
</Button>
<Button onClick={(e) => handleItemClick(e)} name={"3"}>
Wednesday
</Button>
</Grid>
</Container>
<Container>
{activeItem && (
<ScheduledTrainingCard
dayTraining={showSelectedDay(days, activeItem)}
></ScheduledTrainingCard>
)}
</Container>
</Container>
);
return ScheduleComponent;
}
export default ScheduleComponent;
The problem is that you are using return inside map. Look how I did it:
1- We don't need the function showSelectedDay
so I remove it.
2- We don't need the state const [activeItem, setActiveItem] = useState("");
.
3- Add new state const [dayTrainings, setDayTrainings] = useState([]);
4- Update handleItemClick
to:
const [dayTrainings, setDayTrainings] = useState([]);
const handleItemClick = (e) => {
days.forEach((element, index) => {
if (e.target.name === element.id) {
console.log("selected day is " + element.date);
setDayTrainings(element.dayTrainings);
} else {
console.log("not selected, day id is " + element.id);
}
});
};
5- In the render return:
{dayTrainings.length > 0 && (
<ScheduledTrainingCard
dayTraining={dayTrainings}
></ScheduledTrainingCard>
)
Example of ScheduledTrainingCard
:
export default function scheduledTrainingCard(props) {
console.log(props.dayTraining);
return (<>
{
props.dayTraining.map((item, index) =>
<p key={index}>
{item['time']}<br/>
{item['training']}<br/>
{item['trainer']}<br/>
<br/><br/>
</p>)
}
</>);
}
Example of output: output