当前位置: 首页 > news >正文

React中使用Day.js指南

在这里插入图片描述


文章目录

    • 引言
    • 什么是Day.js?
      • Day.js的核心特性
    • 安装和基础配置
      • 安装Day.js
      • 基础导入和使用
    • 在React中的基础使用
      • 1. 显示格式化日期
      • 2. 实时时钟组件
    • 常用插件配置
      • 1. 相对时间插件
      • 2. 高级格式化插件
      • 3. 时区处理插件
    • 实战案例:博客文章时间组件
    • 高级应用场景
      • 1. 日期范围选择器
      • 2. 倒计时组件
    • 性能优化技巧
      • 1. 使用useMemo缓存计算结果
      • 2. 避免重复创建实例
    • 最佳实践
      • 1. 统一的日期格式管理
      • 2. 创建自定义Hook
      • 3. 错误处理
    • 常见问题和解决方案
      • 1. 时区问题
      • 2. 本地化问题
      • 3. 服务端渲染(SSR)问题


引言

在现代前端开发中,日期和时间处理是一个常见且重要的需求。无论是显示文章发布时间、处理用户输入的日期,还是实现复杂的时间计算,我们都需要一个强大而轻量的日期库。Day.js 作为 Moment.js 的现代替代品,以其轻量、API友好和不可变性等特点,成为了 React 项目中处理日期时间的首选工具。

什么是Day.js?

Day.js 是一个轻量级的 JavaScript 日期库,专为现代浏览器设计。它提供了与 Moment.js 类似的 API,但体积仅有 2KB(压缩后),相比 Moment.js 的 67KB 有着显著的优势。

Day.js的核心特性

  • 轻量级:仅2KB的体积
  • 不可变性:所有API都返回新的实例
  • 链式调用:支持方法链式调用
  • 国际化:支持多语言
  • 插件系统:可按需加载功能
  • TypeScript支持:完整的类型定义

安装和基础配置

安装Day.js

# 使用npm
npm install dayjs# 使用yarn
yarn add dayjs# 使用pnpm
pnpm add dayjs

基础导入和使用

import dayjs from 'dayjs'// 创建当前时间
const now = dayjs()// 创建指定时间
const specificDate = dayjs('2024-01-01')
const fromTimestamp = dayjs(1640995200000)

在React中的基础使用

1. 显示格式化日期

import React from 'react'
import dayjs from 'dayjs'const DateDisplay = ({ date }) => {return (<div><p>完整日期: {dayjs(date).format('YYYY-MM-DD HH:mm:ss')}</p><p>相对时间: {dayjs(date).fromNow()}</p><p>友好格式: {dayjs(date).format('MMMM D, YYYY')}</p></div>)
}

2. 实时时钟组件

import React, { useState, useEffect } from 'react'
import dayjs from 'dayjs'const RealTimeClock = () => {const [currentTime, setCurrentTime] = useState(dayjs())useEffect(() => {const timer = setInterval(() => {setCurrentTime(dayjs())}, 1000)return () => clearInterval(timer)}, [])return (<div className="clock"><h2>{currentTime.format('HH:mm:ss')}</h2><p>{currentTime.format('YYYY年MM月DD日 dddd')}</p></div>)
}

常用插件配置

Day.js 采用插件系统来扩展功能,常用的插件包括:

1. 相对时间插件

import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'dayjs.extend(relativeTime)
dayjs.locale('zh-cn')// 使用相对时间
const date = dayjs('2024-01-01')
console.log(date.fromNow()) // "5个月前"

2. 高级格式化插件

import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)// 使用高级格式化
const date = dayjs()
console.log(date.format('Q')) // 季度
console.log(date.format('Do')) // 带序数的日期

3. 时区处理插件

import timezone from 'dayjs/plugin/timezone'
import utc from 'dayjs/plugin/utc'dayjs.extend(utc)
dayjs.extend(timezone)// 时区转换
const utcDate = dayjs.utc('2024-01-01 12:00:00')
const localDate = utcDate.tz('Asia/Shanghai')

实战案例:博客文章时间组件

让我们创建一个完整的博客文章时间显示组件:

import React, { useMemo } from 'react'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'dayjs.extend(relativeTime)
dayjs.locale('zh-cn')const ArticleTime = ({ publishTime, updateTime, showRelative = true,showUpdate = true 
}) => {const publishDate = useMemo(() => dayjs(publishTime), [publishTime])const updateDate = useMemo(() => updateTime ? dayjs(updateTime) : null, [updateTime])const isRecent = useMemo(() => publishDate.isAfter(dayjs().subtract(7, 'day')), [publishDate])const isUpdated = useMemo(() => updateDate && updateDate.isAfter(publishDate.add(1, 'day')), [publishDate, updateDate])return (<div className="article-time"><div className="publish-time"><span className="label">发布时间: </span><time dateTime={publishDate.toISOString()}>{showRelative ? publishDate.fromNow() : publishDate.format('YYYY-MM-DD')}</time>{isRecent && <span className="badge new">新</span>}</div>{showUpdate && isUpdated && (<div className="update-time"><span className="label">最后更新: </span><time dateTime={updateDate.toISOString()}>{showRelative ? updateDate.fromNow() : updateDate.format('YYYY-MM-DD')}</time><span className="badge updated">已更新</span></div>)}</div>)
}export default ArticleTime

高级应用场景

1. 日期范围选择器

import React, { useState } from 'react'
import dayjs from 'dayjs'
import isBetween from 'dayjs/plugin/isBetween'dayjs.extend(isBetween)const DateRangePicker = ({ onRangeChange }) => {const [startDate, setStartDate] = useState('')const [endDate, setEndDate] = useState('')const handleRangeChange = () => {if (startDate && endDate) {const start = dayjs(startDate)const end = dayjs(endDate)if (start.isAfter(end)) {alert('开始日期不能晚于结束日期')return}const daysDiff = end.diff(start, 'day')onRangeChange({start: start.format('YYYY-MM-DD'),end: end.format('YYYY-MM-DD'),days: daysDiff + 1})}}return (<div className="date-range-picker"><inputtype="date"value={startDate}onChange={(e) => setStartDate(e.target.value)}max={endDate || dayjs().format('YYYY-MM-DD')}/><span>到</span><inputtype="date"value={endDate}onChange={(e) => setEndDate(e.target.value)}min={startDate}max={dayjs().format('YYYY-MM-DD')}/><button onClick={handleRangeChange}>确认</button></div>)
}

2. 倒计时组件

import React, { useState, useEffect } from 'react'
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'dayjs.extend(duration)const Countdown = ({ targetDate, onComplete }) => {const [timeLeft, setTimeLeft] = useState(null)useEffect(() => {const target = dayjs(targetDate)const updateCountdown = () => {const now = dayjs()const diff = target.diff(now)if (diff <= 0) {setTimeLeft(null)onComplete && onComplete()return}const duration = dayjs.duration(diff)setTimeLeft({days: Math.floor(duration.asDays()),hours: duration.hours(),minutes: duration.minutes(),seconds: duration.seconds()})}updateCountdown()const timer = setInterval(updateCountdown, 1000)return () => clearInterval(timer)}, [targetDate, onComplete])if (!timeLeft) {return <div className="countdown finished">时间到!</div>}return (<div className="countdown"><div className="time-unit"><span className="number">{timeLeft.days}</span><span className="label">天</span></div><div className="time-unit"><span className="number">{timeLeft.hours}</span><span className="label">时</span></div><div className="time-unit"><span className="number">{timeLeft.minutes}</span><span className="label">分</span></div><div className="time-unit"><span className="number">{timeLeft.seconds}</span><span className="label">秒</span></div></div>)
}

性能优化技巧

1. 使用useMemo缓存计算结果

import React, { useMemo } from 'react'
import dayjs from 'dayjs'const OptimizedDateComponent = ({ dates }) => {const sortedDates = useMemo(() => {return dates.map(date => dayjs(date)).sort((a, b) => a.valueOf() - b.valueOf()).map(date => date.format('YYYY-MM-DD'))}, [dates])return (<ul>{sortedDates.map((date, index) => (<li key={index}>{date}</li>))}</ul>)
}

2. 避免重复创建实例

// 不推荐
const BadExample = ({ timestamp }) => {return (<div><p>{dayjs(timestamp).format('YYYY-MM-DD')}</p><p>{dayjs(timestamp).format('HH:mm:ss')}</p><p>{dayjs(timestamp).fromNow()}</p></div>)
}// 推荐
const GoodExample = ({ timestamp }) => {const date = useMemo(() => dayjs(timestamp), [timestamp])return (<div><p>{date.format('YYYY-MM-DD')}</p><p>{date.format('HH:mm:ss')}</p><p>{date.fromNow()}</p></div>)
}

最佳实践

1. 统一的日期格式管理

// utils/dateFormats.js
export const DATE_FORMATS = {DISPLAY: 'YYYY年MM月DD日',INPUT: 'YYYY-MM-DD',DATETIME: 'YYYY-MM-DD HH:mm:ss',TIME: 'HH:mm:ss',MONTH: 'YYYY-MM',YEAR: 'YYYY'
}// 使用
import { DATE_FORMATS } from './utils/dateFormats'
const formattedDate = dayjs(date).format(DATE_FORMATS.DISPLAY)

2. 创建自定义Hook

import { useState, useEffect } from 'react'
import dayjs from 'dayjs'export const useCurrentTime = (updateInterval = 1000) => {const [currentTime, setCurrentTime] = useState(dayjs())useEffect(() => {const timer = setInterval(() => {setCurrentTime(dayjs())}, updateInterval)return () => clearInterval(timer)}, [updateInterval])return currentTime
}// 使用
const MyComponent = () => {const currentTime = useCurrentTime()return <div>{currentTime.format('HH:mm:ss')}</div>
}

3. 错误处理

const SafeDateComponent = ({ dateString }) => {const formatDate = (date) => {try {const dayObj = dayjs(date)if (!dayObj.isValid()) {return '无效日期'}return dayObj.format('YYYY-MM-DD')} catch (error) {console.error('日期格式化错误:', error)return '日期格式错误'}}return <div>{formatDate(dateString)}</div>
}

常见问题和解决方案

1. 时区问题

// 始终使用UTC时间进行存储和传输
const saveDate = dayjs().utc().toISOString()// 在显示时转换为本地时间
const displayDate = dayjs.utc(saveDate).local()

2. 本地化问题

import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn'
import 'dayjs/locale/en'// 根据用户设置切换语言
const setLanguage = (lang) => {dayjs.locale(lang)
}

3. 服务端渲染(SSR)问题

import { useEffect, useState } from 'react'
import dayjs from 'dayjs'const SSRSafeDateComponent = ({ date }) => {const [mounted, setMounted] = useState(false)useEffect(() => {setMounted(true)}, [])if (!mounted) {return <div>加载中...</div>}return <div>{dayjs(date).format('YYYY-MM-DD')}</div>
}

相关文章:

  • 使用NVIDIA NeMo Agent Toolkit扩展现实机器人仿真的物理AI应用
  • 228永磁同步电机无速度算法--基于双重锁相环的滑模观测器
  • 如何调优Kafka
  • 深入解析JVM类加载机制
  • MATLAB交互式贝塞尔曲线演示
  • 动态多目标进化算法:基于迁移学习的动态多目标遗传算法Tr-NSGA-II求解CEC2015,提供完整MATLAB代码
  • QSimpleUpdater:解锁 Qt 应用自动更新的全新姿势
  • 在docker中部署mysql
  • 计算机网络笔记(四十二)——6.5电子邮件
  • http1.x VS http2.x 协议
  • csharp设计方法
  • Qt--信号槽发送QVector
  • 专注于PLC数据采集MES交互解决方案
  • Redis集群模式之Redis Cluster(3)
  • 【0.2 漫画操作系统原理】
  • 从0开始学习R语言--Day23--稳健回归
  • volka烹饪常用英语
  • Salesforce 推出Marketing Cloud Next营销云
  • Docker 部署 PostgreSQL 指南
  • 0x-5-ORA-03113-ORA-01081-记一次删归档改spfile-开实例
  • 哈尔滨网站建设乙薇/seo项目是什么
  • 怎么做赌钱网站/营销策划机构
  • 南昌商城网站建设/广州网站设计
  • 网站的中英文切换怎么做的/百度的代理商有哪些
  • 建筑规范网站/抖音广告
  • 网站做授权登录/seo外链发布平台