Библиотека date-fns используется в React как набор чистых функций для работы с датами без состояния и скрытых зависимостей. Такой подход делает её предсказуемой в компонентах, облегчает тестирование и снижает риск побочных эффектов при ререндере.
Основной принцип интеграции — импортировать только нужные функции, избегая полного подключения библиотеки.
import { format, addDays, isAfter, parseISO } from "date-fns";
Каждая функция является независимой, что позволяет Tree Shaking и уменьшает итоговый бандл.
Одной из самых частых задач является отображение даты в UI. В React форматирование обычно выполняется прямо в render-логике или через вычисляемые значения.
import { format } from "date-fns";
function PostDate({ createdAt }) {
return (
<time>
{format(new Date(createdAt), "dd.MM.yyyy")}
</time>
);
}
Функция format не хранит состояния и не зависит от
окружения, поэтому её безопасно вызывать при каждом рендере.
При частых рендерах форматирование даты может выполняться
многократно. Для оптимизации используется useMemo, особенно
если вычисления сложнее простого форматирования.
import { useMemo } from "react";
import { format } from "date-fns";
function EventCard({ event }) {
const formattedDate = useMemo(() => {
return format(new Date(event.startDate), "EEEE, d MMMM yyyy");
}, [event.startDate]);
return <div>{formattedDate}</div>;
}
useMemo предотвращает повторное вычисление при
неизменном startDate, снижая нагрузку на рендеринг.
В интерфейсах часто требуется отображение разницы во времени: «2 дня
назад», «через 3 часа». В date-fns для этого используется
formatDistanceToNow.
import { formatDistanceToNow } from "date-fns";
function CommentTime({ date }) {
return (
<span>
{formatDistanceToNow(new Date(date), { addSuffix: true })}
</span>
);
}
Эта функция автоматически вычисляет разницу относительно текущего времени, что делает её удобной для лент и комментариев.
В React-приложениях даты часто приходят с API в ISO-формате. Для
безопасного преобразования используется parseISO.
import { parseISO, format } from "date-fns";
function Booking({ data }) {
const date = parseISO(data.start_time);
return <div>{format(date, "dd MMM yyyy HH:mm")}</div>;
}
Использование new Date() допустимо, но
parseISO обеспечивает более предсказуемое поведение при
строгих строковых форматах.
React-компоненты часто зависят от состояния даты: активность, доступность, истечение срока.
import { isAfter } from "date-fns";
function Promo({ expiresAt }) {
const isExpired = isAfter(new Date(), new Date(expiresAt));
return (
<button disabled={isExpired}>
Купить
</button>
);
}
Функции сравнения из date-fns позволяют избегать ручных вычислений через timestamp и делают код более декларативным.
Часто требуется вычислять будущие или прошлые даты: дедлайны, напоминания, расписания.
import { addDays, subHours } from "date-fns";
const deadline = addDays(new Date(), 7);
const reminder = subHours(deadline, 2);
В React такие вычисления обычно используются при подготовке данных перед рендером или внутри хуков.
date-fns поддерживает локализацию через отдельные модули локалей. Это важно для интерфейсов с несколькими языками.
import { format } from "date-fns";
import { ru } from "date-fns/locale";
function LocalizedDate({ date }) {
return (
<div>
{format(new Date(date), "d MMMM yyyy", { locale: ru })}
</div>
);
}
Локаль передаётся явно, что исключает глобальные зависимости и упрощает контроль над выводом.
В сложных интерфейсах логика работы с датами выносится в кастомные хуки.
import { useMemo } from "react";
import { format, isBefore } from "date-fns";
function useEventStatus(eventDate) {
return useMemo(() => {
const date = new Date(eventDate);
return {
formatted: format(date, "dd.MM.yyyy"),
isPast: isBefore(date, new Date())
};
}, [eventDate]);
}
Такой подход отделяет бизнес-логику от UI-компонентов.
В серверном рендеринге (например, Next.js) важно учитывать различие часовых поясов между сервером и клиентом. date-fns работает детерминированно, но результат форматирования может зависеть от окружения.
import { format } from "date-fns";
export async function getServerSideProps() {
const now = new Date();
return {
props: {
time: format(now, "yyyy-MM-dd HH:mm:ss")
}
};
}
Чтобы избежать расхождений между сервером и клиентом, форматирование часто фиксируется на уровне сервера, а клиент получает уже готовую строку.
В React-проектах распространена практика отделения работы с датами от компонентов. date-fns используется в утилитарных модулях.
// utils/date.js
import { format, isToday } from "date-fns";
export function formatMessageDate(date) {
const d = new Date(date);
if (isToday(d)) {
return format(d, "HH:mm");
}
return format(d, "dd.MM.yyyy");
}
import { formatMessageDate } from "./utils/date";
function Message({ message }) {
return <span>{formatMessageDate(message.createdAt)}</span>;
}
Такой подход снижает связность компонентов и упрощает повторное использование логики.
React часто отображает списки событий, где каждую дату необходимо обработать.
import { format } from "date-fns";
function Timeline({ events }) {
return (
<ul>
{events.map((event) => (
<li key={event.id}>
{format(new Date(event.date), "dd.MM.yyyy")} — {event.title}
</li>
))}
</ul>
);
}
При больших списках стоит учитывать стоимость преобразований и выносить вычисления за пределы render при возможности.
React может вызывать рендеры часто, особенно при изменении состояния родительских компонентов. date-fns-функции не кэшируют результаты, поэтому повторные вызовы всегда выполняют вычисления заново.
Для стабилизации используются:
useMemo для вычислений внутри компонентовДля построения UI таймеров и дедлайнов используется комбинация функций date-fns и React state.
import { useEffect, useState } from "react";
import { differenceInSeconds } from "date-fns";
function Countdown({ targetDate }) {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const target = new Date(targetDate);
const id = setInterval(() => {
setSeconds(differenceInSeconds(target, new Date()));
}, 1000);
return () => clearInterval(id);
}, [targetDate]);
return <div>{seconds}</div>;
}
Такой подход позволяет строить реактивные интерфейсы без сторонних библиотек состояния времени.
При росте приложения date-fns обычно становится центральным инструментом работы с датами во всех слоях:
Ключевое преимущество — отсутствие глобального состояния и минимальная связность между модулями, что позволяет безопасно использовать функции в любом контексте React-архитектуры.