ReactJS基于PST时区日期实现react-router-dom条件路由
实现方案
整体分两步实现:先写不依赖用户本地时区的PST时间判断逻辑,再基于react-router-dom的路由能力做访问拦截重定向。
PST基准时间判断逻辑
禁止直接调用new Date().getDay()取星期,这个接口返回的是用户设备本地时区的结果,不符合要求。根据你是否需要考虑太平洋夏令时,二选一实现判断函数即可:
- 严格遵循PST(固定UTC-8偏移,不随夏令时切换):直接基于UTC时间做偏移计算,结果100%符合固定PST要求
- 适配美国西海岸实际民用时间(自动切换PST/PDT夏令时):用浏览器原生
Intl.DateTimeFormat接口指定太平洋时区解析,不需要引入第三方时间库
判断函数代码如下:
/** * 判断当前PST时间是否为工作日(周一至周五) * @returns {boolean} true=工作日可访问表单,false=周末需重定向 */ const isPstWorkday = () => { // ------------ 固定PST(UTC-8)逻辑 ------------ const now = new Date(); // 先转UTC时间戳,再减8小时得到PST时间 const utcTimestamp = now.getTime() + now.getTimezoneOffset() * 60 * 1000; const pstDate = new Date(utcTimestamp - 8 * 60 * 60 * 1000); const pstWeekday = pstDate.getDay(); // getDay返回0=周日,1-5=周一到周五,6=周六 return pstWeekday >= 1 && pstWeekday <= 5; // ------------ 如果需要适配夏令时(PDT),替换为以下逻辑 ------------ // const weekdayFormatter = new Intl.DateTimeFormat('en-US', { // timeZone: 'America/Los_Angeles', // weekday: 'long' // }); // const dayMap = { // Sunday: 0, // Monday: 1, // Tuesday: 2, // Wednesday: 3, // Thursday: 4, // Friday: 5, // Saturday: 6 // }; // const pstWeekday = dayMap[weekdayFormatter.format(new Date())]; // return pstWeekday >= 1 && pstWeekday <= 5; };
react-router-dom 路由拦截实现
以当前主流的v6版本为例,用受保护路由(路由守卫)的模式实现,不要在单个页面组件内写跳转逻辑,耦合度太高。
- 先封装通用的表单页路由守卫组件,内部做时间判断,符合条件渲染目标页面,不符合直接重定向:
import { Navigate } from 'react-router-dom'; import { useEffect, useState } from 'react'; const FormProtectedRoute = ({ element }) => { const [allowAccess, setAllowAccess] = useState(isPstWorkday()); // 可选:每分钟轮询校验一次时间,避免用户停留页面跨周末/工作日分界点不触发跳转 useEffect(() => { const checkTimer = setInterval(() => { setAllowAccess(isPstWorkday()); }, 60 * 1000); return () => clearInterval(checkTimer); }, []); return allowAccess ? element : <Navigate to="/site-closed" replace />; };
- 在路由配置中使用封装好的守卫组件包裹表单页路由即可:
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import Home from './pages/Home'; import FormPage from './pages/FormPage'; import SiteClosed from './pages/SiteClosed'; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> {/* 表单页走守卫逻辑 */} <Route path="/form" element={<FormProtectedRoute element={<FormPage />} />} /> <Route path="/site-closed" element={<SiteClosed />} /> {/* 其余业务路由正常配置 */} </Routes> </BrowserRouter> ); }
注意事项
- 如果你还在使用react-router-dom v5版本,把代码里的
<Navigate>替换为<Redirect>即可,整体逻辑完全一致。 - 前端拦截仅做用户体验层面的控制,如果表单提交涉及敏感数据或核心业务逻辑,必须在后端服务层也加一层PST时间校验,前端逻辑可以被用户通过篡改本地代码绕过。
内容的提问来源于stack exchange,提问作者whaledarn
相关产品推荐
相关产品推荐

