首页 > 其他分享 >React+TS前台项目实战(三十)-- 首页构建之基于react-query和性能hook实现全页面数据渲染

React+TS前台项目实战(三十)-- 首页构建之基于react-query和性能hook实现全页面数据渲染

时间:2024-07-16 13:27:19浏览次数:9  
标签:const width -- TS react item statistic import 区块

文章目录


前言

前三篇文章详细介绍了首页的响应式布局,采用关注点分离进行模块拆解,现在只需按需引入模块,页面更加简洁,代码的维护性得到提升。今天将进入首页的收尾阶段,即完成剩余区块列表、交易列表接口数据渲染,轮训,各种钩子使用以提升性能。


一、效果展示

(1)PC端区块列表、交易列表轮询

在这里插入图片描述

(2)PC端搜索查询

在这里插入图片描述

(3)移动端区块列表、交易列表轮询

在这里插入图片描述

(4)移动端搜索查询

在这里插入图片描述

二、首页源码+详细注释说明+技术分析

1. 页面功能分析

(1)页面组成:页面由渲染Banner、搜索块、统计项、哈希速率图表、区块时间图表、区块列表和交易列表等模块组成
(2)数据获取:使用@tanstack/react-query库进行数据获取、缓存、轮训
(3)性能处理:使用React钩子,如useMemo、useTranslation来管理状态、获取数据和国际化,提升性能
(4)自定义钩子使用:使用自定义钩子useStatistics生成并显示统计数据
(5)详细模块封装请看前面三讲首页响应式构建之banner/搜索/统计模块布局首页响应式构建之区块/交易布局优化实现首页Echarts模块数据渲染

2. 代码+详细注释

// @/page/Home/index.tsx
import { FC, useMemo } from "react";
import classNames from "classnames";
import { useTranslation } from "react-i18next";
import { useQuery } from "@tanstack/react-query";
import Content from "@/components/Content";
import Banner from "./Banner";
import SearchBlock from "./SearchBlock";
import HashRateEchart from "./HashRateEchart/index";
import BlockTimeChart from "./BlockTimeChart/index";
import BlockList from "./BlockList";
import TranctionList from "./TranctionList";
import { HomeStatisticBlock, HomeStatisticItem, HomeTableBlock } from "./styled";
import { queryBlocks, queryTransactions } from "@/api/home";
import { BLOCK_POLLING_TIME } from "@/global/constants/common";
import { useStatistics } from "./requester";
const HomePage: FC = () => {
  // 使用useQuery,异步获取最新的区块数据
  const blocksQuery = useQuery(
    ["latest_blocks"],
    async () => {
      const { data } = await queryBlocks({
        page: 1, // 从第一页开始获取
        page_size: 25, // 每页获取25个区块
      });
      // 将获取到的区块数据转换为我们需要的格式
      const blocks = data.map((wrapper: any) => {
        return {
          ...wrapper.attributes,
        };
      });
      return {
        blocks, // 最新的区块列表
        total: data?.length, // 最新区块的总数
      };
    },
    {
      refetchInterval: BLOCK_POLLING_TIME, // 每隔一段时间重新获取最新的区块数据
    }
  );
  // 使用useMemo钩子,blocksQuery数据变化时,重新获取
  const blocks = useMemo(() => blocksQuery.data?.blocks.slice(0, 10) ?? [], [blocksQuery.data?.blocks]);
  // 使用useQuery,异步获取最新的交易数据
  const transactionsQuery = useQuery(
    ["latest_transactions"],
    async () => {
      const { data } = await queryTransactions({
        page: 1,
        page_size: 25,
      });
      const transactions = data.map((wrapper: any) => {
        return {
          ...wrapper.attributes,
        };
      });
      // 将获取到的交易数据转换为我们需要的格式
      return {
        transactions,
        total: transactions?.length,
      };
    },
    {
      refetchInterval: BLOCK_POLLING_TIME,
    }
  );
  // 使用useMemo钩子,transactionsQuery数据变化时,重新获取
  const transactions = useMemo(() => transactionsQuery.data?.transactions.slice(0, 10) ?? [], [transactionsQuery.data?.transactions]);

  // 定义统计数据类型声明
  interface EchartsAndData {
    name: string;
    value: string;
  }
  const useEchartsAndDataList = (): EchartsAndData[] => {
    const { t } = useTranslation();
    const statistics = useStatistics();
    return [
      {
        name: t("home.echartsAndData.name1"),
        value: t(statistics.value1),
      },
      {
        name: t("home.echartsAndData.name2"),
        value: t(statistics.value2),
      },
      {
        name: t("home.echartsAndData.name3"),
        value: t(statistics.value3),
      },
      {
        name: t("home.echartsAndData.name4"),
        value: t(statistics.value4),
      },
    ];
  };
  // 使用区块链统计数据
  const echartsAndDataList = useEchartsAndDataList();
  // 统计数据渲染结构体
  const StatisticItem = ({ data }: { data: EchartsAndData }) => (
    <HomeStatisticItem>
      <div className={classNames("statistic-item-left-title")}>{data.name}</div>
      <div className={classNames("statistic-item-left-value")}>{data.value}</div>
    </HomeStatisticItem>
  );
  return (
    <Content>
      {/* Banner模块 */}
      <Banner />
      <div className="container">
        {/* 搜索模块 */}
        <SearchBlock />
        {/* echarts图表以及统计数据模块 */}
        <HomeStatisticBlock>
          <div className={classNames("statistic-item")}>
            <div className={classNames("statistic-item-left")}>
              {/* 统计数据 */}
              <StatisticItem data={echartsAndDataList[0]}></StatisticItem>
              <StatisticItem data={echartsAndDataList[1]}></StatisticItem>
            </div>
            <div className={classNames("statistic-item-right")}>
              {/* 统计图表 */}
              <HashRateEchart />
            </div>
          </div>
          <div className={classNames("statistic-item")}>
            <div className={classNames("statistic-item-left")}>
              {/* 统计数据 */}
              <StatisticItem data={echartsAndDataList[2]}></StatisticItem>
              <StatisticItem data={echartsAndDataList[3]}></StatisticItem>
            </div>
            <div className={classNames("statistic-item-right")}>
              {/* 统计图表 */}
              <BlockTimeChart />
            </div>
          </div>
        </HomeStatisticBlock>
      </div>
      <HomeTableBlock className="container">
        {/* 区块列表模块 */}
        <BlockList blocks={blocks} />
        {/* 交易列表模块 */}
        <TranctionList transactions={transactions} />
      </HomeTableBlock>
    </Content>
  );
};
export default HomePage;
----------------------------------------------------------------------------------------------------
// @/pages/Home/styled.tsx
import styled from "styled-components";
import variables from "@/styles/variables.module.scss";
export const HomeStatisticBlock = styled.div`
  width: 100%;
  height: 207px;
  display: flex;
  margin-bottom: 20px;
  .statistic-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 1;
    background: #232323;
    @media (max-width: ${variables.extraLargeBreakPoint}) {
      flex-direction: column;
    }
    @media (max-width: ${variables.mobileBreakPoint}) {
    }
    .statistic-item-left {
      flex: 1;
      width: 100%;
      height: 100%;
    }
    .statistic-item-right {
      flex: 2;
      width: 100%;
      height: 100%;
      padding: 10px;
      // background: linear-gradient(304deg, #6e85e0 2%, #577cdb 48%, #486ecc 99%);
      @media (max-width: ${variables.extraLargeBreakPoint}) {
      }
      @media (max-width: ${variables.mobileBreakPoint}) {
      }
    }
    &:last-child {
      background: #484e4e;
    }
  }
  @media (max-width: ${variables.extraLargeBreakPoint}) {
    height: 310px;
  }
  @media (max-width: ${variables.mobileBreakPoint}) {
    flex-direction: column;
    height: auto;
  }
`;
export const HomeStatisticItem = styled.div`
  padding: 30px;
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  color: #fff;
  .statistic-item-left-title {
    font-size: 14px;
    margin-bottom: 5px;
  }
  .statistic-item-left-value {
    font-size: 18px;
    font-weight: bold;
  }
  @media (max-width: ${variables.extraLargeBreakPoint}) {
    padding: 15px 30px;
    flex-direction: row;
    margin-bottom: 0;
    .statistic-item-left-value {
      font-size: 16px;
    }
  }
  @media (max-width: ${variables.mobileBreakPoint}) {
    padding: 10px 20px;
  }
`;
export const HomeTableBlock = styled.div`
  display: flex;
  @media (max-width: ${variables.extraLargeBreakPoint}) {
  }
  @media (max-width: ${variables.mobileBreakPoint}) {
    flex-direction: column;
  }
`;

总结

有人可能会说频繁轮询接口会不会影响性能,当然会,但是我们做了一些措施,可以有效地优化性能。首先,我们使用了useMemo和memo等性能钩子函数,就是为了避免重复渲染。同时,使用useQuery处理请求时,它提供了一些性能优化的功能,比如自动缓存和懒加载。关注本栏目,会实时更新。

标签:const,width,--,TS,react,item,statistic,import,区块
From: https://blog.csdn.net/weixin_43883615/article/details/140337199

相关文章

  • Windows安装Python超详细教程
    安装Python3(Windows)有的同学问道怎么安装Python。我们今天讲一下在Windows上安装Python。Python有两个大版本,一个是Python2,另外一个是Python3。目前各种代码以及平台都在往Python3迁移,新项目直接采用Python3。对于新学习的朋友来说,可以直接从Python3开始入手。下载Python......
  • vite react Typescript 构建一个移动端网页
    使用Vite、React和TypeScript来构建一个移动端网页是一个高效且现代的开发方式。Vite是一个构建工具和开发服务器,它利用原生ES模块导入来提供快速的冷启动和即时模块热更新(HMR)。React是用于构建用户界面的JavaScript库,而TypeScript是JavaScript的一个超集,它添......
  • Elasticsearch基础(二)
    4.RestAPIES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:ElasticsearchClients|Elastic其中的JavaRestClient又包括两种:JavaLowLevelRestClientJavaHighLevelRestClient学习JavaHighL......
  • C++游戏篇1“很好的游戏,使我手指旋转”(原创)
    话不多说,上代码!#include<bits/stdc++.h>#include<windows.h>usingnamespacestd;intGe,Fen,timp,F,a[22][6];doubleShi,B;voidS(intForgC,intBackC){WORDwColor=((BackC&0x0F)<<4)+(ForgC&0x0F);SetConsoleTextAttribute(GetS......
  • C++转换进制
    前言本蒟蒻:让C++转进制?我都不会转,更何况让C++转。正文转进制,我们要知道36进制的0-35都用什么表示。0-9就是0-9,而10-35分别是ABCDEFG........RSTUVWXYZ。我们可以设一个字符串表示0-35:strings="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";重要的一步来了,参考以下方法,用while......
  • 嵌入式入职上班第一天:读懂保护与解读保护
    摘要:作为一名嵌入式工程师,了解和掌握保护机制至关重要。本文将为大家介绍嵌入式系统中常见的保护机制,帮助新入职的嵌入式工程师快速上手。#正文:##一、引言嵌入式系统在各个领域都有广泛的应用,为了保证系统的稳定性和安全性,各种保护机制应运而生。作为一名嵌入式新入职的......
  • 推荐2款.NET开源、轻便、实用的Windows桌面启动器
    FlowLauncherFlowLauncher是一款.NET开源(MITLicense)、免费、功能强大、方便实用的Windows文件搜索和应用程序启动器,能够帮助你快速查找文件、启动应用程序和执行系统操作,提高工作效率和操作便利性。并且生态完善,有插件商店,你可以查看完整的插件列表,或通过"设置"中的"插件......
  • CodeForces 1992E Novice's Mistake
    题目链接:CodeForces1992E【Novice'sMistake】思路    直接对a,b枚举肯定会超时,因为a,b数数字过大,但是通过结果a*n-b可以发现结果最多为6位数,所以对结果的位数进行枚举,然后枚举a,来计算出b并判断是否符合题意,同时需要去掉b不符合题目的范围的情况。代码#includ......
  • 独立高防服务器特点免费全能空间存在吗
    独立高防服务器,是在独享整台服务器硬件资源和卓越性能的基础上独立高防服务器有哪些特点呢?因为独立高防服务器具有超强稳定性,用户可安装独立的操作系统,http、ftp、ssh、sendmail、mysql等都是独立的,只有你一个人在用,不像虚拟主机一样是免费服务器很多人共享,在安全性、性能、......
  • Nuclei的安装
    一、安装基础Golang通过yuminstallgo安装的go版本是1.20.14,无法满足nuclei的环境要求,使用yumremovego卸载删除已安装的go语言环境,通过go官网下载需要的go版本,https://go.dev/dl/  下载在/usr/local目录下,cd/usr/local,wget https://go.dev/dl/go1.22.4.linux-......