当我使用 while 循环时,我的 react-native-app 冻结了
My react-native-app freezes when i use while loop
此组件向患者显示日历,以便他们可以 select 从医生的预约日开始预约。医生预约日期是从 api 中获取的。我想要实现的是禁用日历中除医生预约日之外的所有其他工作日,以便患者只能按其中一个预约日。我正在使用 react-native-calendars 库和 date-fns-library 作为日期。但是,我的应用程序在定义循环时冻结一次。我在这里做错了什么?还有没有更好的方法来实现我想要实现的目标?
import { View } from "react-native";
import React, { useEffect, useState } from "react";
import { Calendar, CalendarProps } from "react-native-calendars";
import startOfMonth from "date-fns/startOfMonth";
import endOfMonth from "date-fns/endOfMonth";
import isBefore from "date-fns/isBefore";
import addDays from "date-fns/addDays";
import format from "date-fns/format";
import setDay from "date-fns/setDay";
import api from "../../config/api";
import Layout from "../UI/Layout";
import RegularText from "../UI/Text/RegularText";
import { useAppSelector } from "../../store/hooks";
import { useRoute } from "@react-navigation/native";
import { AppointmentDaysScreenRouteProp } from "../../@types/navigation";
const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] as const;
type weekday = typeof weekdays[number];
const CalendarComponent = () => {
const language = useAppSelector((state) => state.language.selected);
const [markedDates, setMarkedDates] = useState<CalendarProps["markedDates"]>(
{}
);
const [disabledledWeekdays, setDisbaledWeekdays] = useState<number[]>([]);
const route = useRoute<AppointmentDaysScreenRouteProp>();
const { doctorId } = route.params;
const [loading, setLoading] = useState(true);
let text = {
loading: "...Please wait",
};
if (language === "اردو") {
text = {
loading: "...لوڈ ہو رہا ہے",
};
}
useEffect(() => {
(async () => {
try {
const res = await api.get<{ appointmentDays: weekday[] }>(
`/appointments/appointmentDays/doctorId/${doctorId}`
);
const { appointmentDays } = res.data;
const disabledDays = weekdays
.filter((item) => !appointmentDays.includes(item))
.map((item) => weekdays.indexOf(item));
const now = new Date();
getDisabledDays(now.getMonth(), now.getFullYear(), disabledDays);
setDisbaledWeekdays(disabledDays);
} finally {
setLoading(false);
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const getDisabledDays = (
month: number,
year: number,
daysIndexes: number[]
) => {
const now = new Date();
now.setFullYear(year, month);
const pivot = startOfMonth(now);
const end = endOfMonth(now);
const dates: CalendarProps["markedDates"] = {};
const disabled = { disabled: true, disableTouchEvent: true };
//THIS WHILE LOOP IS FREEZING MY APP
//IF I REMOVE THIS LOOP APP WORKS FINE
while (isBefore(pivot, end)) {
daysIndexes.forEach((day) => {
const copy = setDay(new Date(pivot), day);
dates[format(copy, "yyyy-MM-dd")] = disabled;
});
addDays(pivot, 7);
}
setMarkedDates(dates);
return dates;
};
return (
<Layout>
<View>
{loading ? (
<RegularText>{text.loading}</RegularText>
) : (
<Calendar
theme={{
textSectionTitleDisabledColor: "#d9e1e8",
}}
markedDates={markedDates}
onDayPress={(day) => {
console.log("dosomething with ", day);
}}
firstDay={1}
enableSwipeMonths={true}
disabledDaysIndexes={disabledledWeekdays}
onMonthChange={(date) => {
getDisabledDays(date.month - 1, date.year, disabledledWeekdays);
}}
/>
)}
</View>
</Layout>
);
};
export default CalendarComponent;
查看 documentation,我似乎 addDays(date, amount
) 正在返回一个新日期并且没有修改 pivot
的值。尝试做 pivot = addDays(pivot, 7)
此组件向患者显示日历,以便他们可以 select 从医生的预约日开始预约。医生预约日期是从 api 中获取的。我想要实现的是禁用日历中除医生预约日之外的所有其他工作日,以便患者只能按其中一个预约日。我正在使用 react-native-calendars 库和 date-fns-library 作为日期。但是,我的应用程序在定义循环时冻结一次。我在这里做错了什么?还有没有更好的方法来实现我想要实现的目标?
import { View } from "react-native";
import React, { useEffect, useState } from "react";
import { Calendar, CalendarProps } from "react-native-calendars";
import startOfMonth from "date-fns/startOfMonth";
import endOfMonth from "date-fns/endOfMonth";
import isBefore from "date-fns/isBefore";
import addDays from "date-fns/addDays";
import format from "date-fns/format";
import setDay from "date-fns/setDay";
import api from "../../config/api";
import Layout from "../UI/Layout";
import RegularText from "../UI/Text/RegularText";
import { useAppSelector } from "../../store/hooks";
import { useRoute } from "@react-navigation/native";
import { AppointmentDaysScreenRouteProp } from "../../@types/navigation";
const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] as const;
type weekday = typeof weekdays[number];
const CalendarComponent = () => {
const language = useAppSelector((state) => state.language.selected);
const [markedDates, setMarkedDates] = useState<CalendarProps["markedDates"]>(
{}
);
const [disabledledWeekdays, setDisbaledWeekdays] = useState<number[]>([]);
const route = useRoute<AppointmentDaysScreenRouteProp>();
const { doctorId } = route.params;
const [loading, setLoading] = useState(true);
let text = {
loading: "...Please wait",
};
if (language === "اردو") {
text = {
loading: "...لوڈ ہو رہا ہے",
};
}
useEffect(() => {
(async () => {
try {
const res = await api.get<{ appointmentDays: weekday[] }>(
`/appointments/appointmentDays/doctorId/${doctorId}`
);
const { appointmentDays } = res.data;
const disabledDays = weekdays
.filter((item) => !appointmentDays.includes(item))
.map((item) => weekdays.indexOf(item));
const now = new Date();
getDisabledDays(now.getMonth(), now.getFullYear(), disabledDays);
setDisbaledWeekdays(disabledDays);
} finally {
setLoading(false);
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const getDisabledDays = (
month: number,
year: number,
daysIndexes: number[]
) => {
const now = new Date();
now.setFullYear(year, month);
const pivot = startOfMonth(now);
const end = endOfMonth(now);
const dates: CalendarProps["markedDates"] = {};
const disabled = { disabled: true, disableTouchEvent: true };
//THIS WHILE LOOP IS FREEZING MY APP
//IF I REMOVE THIS LOOP APP WORKS FINE
while (isBefore(pivot, end)) {
daysIndexes.forEach((day) => {
const copy = setDay(new Date(pivot), day);
dates[format(copy, "yyyy-MM-dd")] = disabled;
});
addDays(pivot, 7);
}
setMarkedDates(dates);
return dates;
};
return (
<Layout>
<View>
{loading ? (
<RegularText>{text.loading}</RegularText>
) : (
<Calendar
theme={{
textSectionTitleDisabledColor: "#d9e1e8",
}}
markedDates={markedDates}
onDayPress={(day) => {
console.log("dosomething with ", day);
}}
firstDay={1}
enableSwipeMonths={true}
disabledDaysIndexes={disabledledWeekdays}
onMonthChange={(date) => {
getDisabledDays(date.month - 1, date.year, disabledledWeekdays);
}}
/>
)}
</View>
</Layout>
);
};
export default CalendarComponent;
查看 documentation,我似乎 addDays(date, amount
) 正在返回一个新日期并且没有修改 pivot
的值。尝试做 pivot = addDays(pivot, 7)