我正在为我的应用程序使用 Typescript。我在数据库中有两组数据,一组是date
,一组是time
。两者都需要字符串。
我在用户选择日期时发出了一个 POST
请求,并且将为用户选择该时间。我为用户的选择时间何时结束做了一个辅助函数,在这种情况下,我会在前端向他们展示一个提示
“您选择的时间已过期!”
显示该警报后。我强行清除交货时间。我的逻辑工作正常。每当我访问屏幕时,它总是提醒屏幕,这对 UI 和 UX 不利。但我知道 useEffect() 每当我访问该屏幕时都会产生效果,因为依赖关系发生了变化。有什么办法可以在时间到期后只显示一次警报,然后每当用户访问时他们都看不到警报?
PS: I am thinking should I do with something with my helper function
这是我的示例代码,我也在 code-sandbox
中分享了我的代码import "./styles.css";
import { isToday } from "date-fns";
import React, { useEffect } from "react";
export const isEmptyString = (value: string): boolean =>
!value || value.trim().length === 0;
export const isTimeWindowExpired = (date: string, time: string) => {
if (isEmptyString(date)) {
return undefined;
} else {
const [yyyy, mm, dd]: Array<string> = date.split("-");
const d: Date = new Date();
d.setFullYear(+yyyy);
d.setMonth(+mm - 1);
d.setDate(+dd);
if (isToday(d)) {
const matcher = d.toTimeString().match(/(\d{2}:\d{2}):.*/);
if (matcher) {
const [currentLocalTime] = matcher.slice(1);
const [startTime, endTime] = time.split("-");
return currentLocalTime >= startTime && currentLocalTime <= endTime;
}
}
return false;
}
};
const deliveryDate = "2021-06-18";
const deliveryTime = "07:12-07:13";
export default function App() {
useEffect(() => {
const isExpired = isTimeWindowExpired(deliveryDate, deliveryTime);
if (!isExpired) {
alert("delivery_time_expired");
}
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Edit to see some magic happen!</h2>
</div>
);
}
答案 0 :(得分:0)
您可以使用 ref 来跟踪效果是否是第一次触发。
const firstTimeRef = useRef<boolean>(true)
useEffect(() => {
const isExpired = isTimeWindowExpired(deliveryDate, deliveryTime);
if (!isExpired && !firstTimeRef.current) {
alert("delivery_time_expired");
}
firstTimeRef.current = false
}, [deliveryDate, deliveryTime]);
每当 deliveryDate
和 deliveryTime
更改时,效果都会重新运行,并且仅在第一次未运行时才显示警报。
答案 1 :(得分:0)
我会在 localStorage 中设置一个过期值。在组件安装时读取值并检查过期时间。如果过期已过,则显示警报并清除 localStorage,否则在组件保持挂载时为警报设置超时。如果组件在到期之前卸载,请不要忘记清除 useEffect
挂钩清理函数中的超时。
在组件/效果之外,只是将过期值放入本地存储。我正在使用 luxon
库进行日期时间管理。
import { DateTime } from "luxon";
const EXPIRATION_KEY = "expiration";
const deliveryDate = "2021-06-17";
const deliveryTime = "22:45";
let timer: number;
const expiration = DateTime.fromISO(deliveryDate + "T" + deliveryTime);
window.localStorage.setItem(EXPIRATION_KEY, expiration.toISO());
在组件中。
useEffect(() => {
const expirationTrigger = () => {
alert("delivery_time_expired");
window.localStorage.removeItem(EXPIRATION_KEY);
};
const expirationString = window.localStorage.getItem(EXPIRATION_KEY);
if (expirationString) {
const expiration = DateTime.fromISO(expirationString);
if (expiration.diffNow() < 0) {
expirationTrigger();
} else {
timer = setTimeout(expirationTrigger, expiration.diffNow().milliseconds);
}
}
// effect cleanup to clear timeout when component unmounts
return () => clearTimeout(timer);
});