You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不依赖客户端时间追踪应用运行时长并避免组件重渲染

解决思路与实现方案

1. 用独立模块维护同步时间(避开Redux重渲染问题)

不用Redux存储每秒更新的时间,单独写一个模块来维护,完全不会触发组件重渲染:

// appTime.js
let currentSyncedTime = null;
let updateInterval = null;

// 初始化:传入从服务器获取的初始时间戳
export function initSyncedTime(serverTimestamp) {
  currentSyncedTime = serverTimestamp;
  // 每秒自动加1000毫秒,保持与服务器时间同步
  updateInterval = setInterval(() => {
    currentSyncedTime += 1000;
  }, 1000);
}

// 获取当前同步后的时间
export function getCurrentSyncedTime() {
  return currentSyncedTime;
}

// 页面卸载时清理定时器,防止内存泄漏
export function clearSyncedTimeInterval() {
  if (updateInterval) {
    clearInterval(updateInterval);
  }
}

应用启动时(比如入口组件的useEffect里)调用初始化方法:

// App.jsx
import { useEffect } from 'react';
import { initSyncedTime, clearSyncedTimeInterval } from './appTime';

function App() {
  useEffect(() => {
    // 实际项目替换成你的服务器时间接口
    fetch('/api/get-server-timestamp')
      .then(res => res.json())
      .then(data => {
        initSyncedTime(data.timestamp);
      });

    return () => clearSyncedTimeInterval();
  }, []);

  // ... 组件其他逻辑
}

2. 在RTK Query请求中自动注入同步时间

自定义baseQuery,让所有RTK Query请求自动带上同步时间:

// apiSlice.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { getCurrentSyncedTime } from './appTime';

// 自定义baseQuery,注入同步时间
const syncedBaseQuery = async (args, api, extraOptions) => {
  const currentTime = getCurrentSyncedTime();
  let modifiedArgs = args;

  // 根据请求类型修改参数:字符串URL加查询参数,对象形式加请求头
  if (typeof args === 'string') {
    modifiedArgs = `${args}?request-time=${currentTime}`;
  } else if (args.url) {
    modifiedArgs = {
      ...args,
      headers: {
        ...args.headers,
        'X-Request-Timestamp': currentTime,
      },
    };
  }

  // 调用原生fetchBaseQuery发送请求
  return fetchBaseQuery({ baseUrl: '/api' })(modifiedArgs, api, extraOptions);
};

// 创建API slice
export const apiSlice = createApi({
  baseQuery: syncedBaseQuery,
  endpoints: (builder) => ({
    // 示例接口
    fetchUser: builder.query({
      query: (userId) => `/users/${userId}`,
    }),
  }),
});

export const { useFetchUserQuery } = apiSlice;

3. 组件中使用同步时间

组件需要展示时间时,直接调用getCurrentSyncedTime即可。若要实时显示,手动用setInterval更新组件本地状态——仅该组件会重渲染,而非全局:

// TimeDisplay.jsx
import { useState, useEffect } from 'react';
import { getCurrentSyncedTime } from './appTime';

function TimeDisplay() {
  const [currentTime, setCurrentTime] = useState(getCurrentSyncedTime());

  useEffect(() => {
    const interval = setInterval(() => {
      setCurrentTime(getCurrentSyncedTime());
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return <p>当前同步时间:{new Date(currentTime).toLocaleString()}</p>;
}

方案优势

  • 全局时间仅在独立模块维护,无React/Redux状态绑定,避免不必要的全局重渲染
  • 基于服务器初始时间递增,彻底规避客户端时间误差问题
  • RTK Query自动注入时间,无需每个接口重复编写逻辑

内容的提问来源于stack exchange,提问作者wisicoc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:58:12