当前位置: 首页 > 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>
}
http://www.xdnf.cn/news/1033363.html

相关文章:

  • ABC410 : F - Balanced Rectangles
  • MIB 树的来源与实现深度解析
  • 计算机网络学习笔记:运输层概述UDP、TCP对比
  • Arduino入门教程​​​​​​​:4、打印字符到电脑
  • 疫菌QBD案例
  • Gartner《Build Scalable Data Products With This Step-by-Step Framework》学习报告
  • Linux系统安装MongoDB 8.0流程
  • 树莓派智能小车红外避障实验指导书
  • 当遇到“提交失败:404”的问题时,通常表明前端请求的URL无法正确匹配到后端的Servlet或资源。
  • 区间合并:区间合并问题
  • 前端与协议
  • 掌握应用分层:高内聚低耦合的艺术
  • 闲鱼与淘宝跨平台运营的自动化趋势
  • java 设计模式_行为型_17观察者模式
  • 【游资悟道】陈小群成长历史与股市悟道心法
  • Java面向对象this关键字和static关键字
  • Python 爬虫入门 Day 3 - 实现爬虫多页抓取与翻页逻辑
  • android关于native中Thread类的使用
  • Linux 系统目录结构概述-linux024
  • Tauri(2.5.1)+Leptos(0.8.2)开发自用桌面小程序
  • 系统设计基本功:理解语义
  • 【Linux】Linux多路复用-epoll
  • MapReduce技术详解
  • 软件工程的相关名词解释
  • 【力扣 简单 C】141. 环形链表
  • Spring Data JPA全面指南
  • Docker 在尝试连接 Docker Hub 时遇到网络问题(超时)
  • 在Docker上部署datalust/Seq日志服务系统
  • 【DSP笔记 · 第5章】数字滤波器的蓝图:从数学公式到硬件实现的艺术
  • React--》使用vite构建器打造高效的React组件库