Reputation: 453
to simplify the question: I have Three states
THE QUESTION: why my state change one click late.(example in the end)
function 1 - to handle with the hours available:
const handleDay = day => {
setSelectedDay(day);
const dayMeetings = weekMeetings.filter(meet => meet.startDate.split("T")[0] === day.dateString);
let availableHours = hours.map(e => ({ ...e }));
for (let i = 0; i < dayMeetings.length; i++) {
for (let j = 0; j < hours.length; j++) {
if (moment(dayMeetings[i].startDate).format("LT") === hours[j].time) {
availableHours[j].busy = true;
availableHours[j + 1].busy = true;
if (dayMeetings[i].massageType === "sweden" || dayMeetings[i].massageType==="fullbody" ) {
availableHours[j + 2].busy = true;
}
break;
}
}
}
setAvHoursInDay(availableHours);
setAvHoursByType([]);
if (massageType.key !== -1) massageTypeHandler(massageType);
};
function 2 - to manipulate the hours available depend on massage type:
const massageTypeHandler = item => {
setMassageType(item);
let mapDateByType = avHoursInDay.map(e => ({ ...e }));
for (let i = 0; i < avHoursInDay.length; i++) {
if ((i === avHoursInDay.length - 3 && avHoursInDay[i].busy === false && item.key === 2) || item.key === 3) {
mapDateByType[i].busy = true;
}
if (i === avHoursInDay.length - 1 || i === avHoursInDay.length - 2) {
mapDateByType[i].busy = true;
} else if (avHoursInDay[i].busy === false) {
if (avHoursInDay[i + 1].busy === true) {
mapDateByType[i].busy = true;
} else if ((item.key === 2 || item.key === 3) && avHoursInDay[i + 2].busy === true) {
mapDateByType[i].busy = true;
}
}
}
setAvHoursByType(mapDateByType);
};
=======================
now i have flatList that when user clicked its go to function 2:
renderItem={({ item }) => (
<StyledButton
key={item.key}
onPress={() => massageTypeHandler(item)}
buttonStyle={
item.key === massageType.key
? [styles.massagetypebutton, styles.selectedbutton]
: styles.massagetypebutton
}
text={item.massageType}
/>
)}
keyExtractor={item => item.key.toString()}
/>
and calendar that go to function 1 (that invoke function 2 also):
<Calendar
minDate={new Date()}
markedDates={{
[selectedDay.dateString]: {
selected: true,
disableTouchEvent: true,
},
}}
theme={calendarTheme}
onDayPress={handleDay}
style={{ marginTop: 10 }}
/>
{selectedDay && (
<Text style={styles.daytitle}>יום {moment(selectedDay.dateString).format("dddd DD/MM/YYYY")}</Text>
)}
<AvailableHours avHoursInDay={avHoursByType} />
the question in extend: everything worked correctly and state change to the right available places. but every render change only one click after . for exmaple:
something updated in late..
help please , thanks in advance,
(I would be very happy if you could give me a code review if you see a faster way than two such long functions)
Upvotes: 0
Views: 88
Reputation: 91
lift-state-up and use useReducer
in order to manipulate multiple states fields simultaneously.
function FooCalendar() {
const [state, action] = useReducer(
/* your initial state & implementation, move your BL logic to the reducer */
)
// pass the state to your components
const { selectedDay, avHoursByType } = state;
return (
<>
<Calendar
minDate={new Date()}
markedDates={{
[selectedDay.dateString]: {
selected: true,
disableTouchEvent: true,
},
}}
theme={calendarTheme}
onDayPress={(day) => {
action({payload: {day}, type: 'DATE_CHANGED' })}
}
style={{ marginTop: 10 }}
/>
{selectedDay && (
<Text style={styles.daytitle}>
יום {moment(selectedDay.dateString).format('dddd DD/MM/YYYY')}
</Text>
)}
<AvailableHours avHoursInDay={avHoursByType} onMessageTypeChanged={(item) => {
action({payload: {item}, type: 'MESSAGE_TYPE_CHANGED' })
}} />
</>
);
}
Upvotes: 1