React+TypeScript结合AntD的引导页代码精简优化方案
问题核心原因
你代码里的splashs.map()遍历是完全无效的冗余逻辑:引导页同一时间只展示index对应的单页内容,根本不需要把3个引导页全部遍历渲染。你在map回调里解构的splash是循环过程中的每一个数组元素,不是当前激活的目标项,所以解构出来的属性根本没法直接用,才会反复写splashs[index].xxx做重复访问。
优化方案
1. 删掉无意义的全量遍历,直接获取当前激活页对象
不需要循环整个数组,直接在组件逻辑层根据当前索引取出目标页对象,一次性解构所有需要的属性,后续JSX直接调用解构后的变量即可:
// 直接取当前激活的引导页 const currentSplash = splashs[index]; const { id, title, description, background } = currentSplash;
注:原代码里属性名desctiption是拼写错误,已修正为标准的description,避免后续踩坑
2. 同步清理其他冗余逻辑
- 三个跳转到登录页的方法逻辑完全重复,合并为一个统一方法即可
- 底部指示点长度直接用
splashs.length,不要硬编码写死3,后续增减引导页不需要改业务逻辑 - 索引更新用函数式写法,修复快速点击时的闭包状态错误
- 补全图片
alt属性,符合无障碍规范 - 提前计算
isFirstPage/isLastPage布尔值,减少JSX里重复的判断逻辑
优化后完整代码
import React, { useState } from 'react'; import { useNavigate } from "react-router-dom"; import { Row, Col, Button } from 'antd'; import { ArrowRightOutlined } from '@ant-design/icons'; import Container from '../../Components/UI/Container/Container' import classes from './Splash.module.css'; import { backgroundSplash1, backgroundSplash2, logoImage } from '../../Assets/index'; const Splash = () => { const navigate = useNavigate(); const [index, setIndex] = useState<number>(0); // 解构样式类名 const { splash, bg, BgGradiant, context, content, backgroundImage, logo, btns, btnLogin, btnSkip, dots, dot, dotActive, dotDeActive, contentInner, contentInner1, contentInner2, } = classes // 引导页配置 const splashs = [ { id: 0, title: 'Page 1 : title 1', description: '1- Lorem ipsum 1 ', background: logoImage, }, { id: 1, title: 'Page 2 : title 2', description: '2- Lorem ipsum 2 ', background: backgroundSplash1, }, { id: 2, title: 'Page 3 : title3', description: '3- Lorem ipsum 3', background: backgroundSplash2, } ]; // 统一跳转登录页逻辑 const goLogin = () => navigate("/login"); // 下一页逻辑 const handleNext = () => { setIndex(prev => { if (prev === splashs.length - 1) { goLogin(); return prev; } return prev + 1; }) } // 提前拿当前页属性、状态判断值 const currentSplash = splashs[index]; const { id, title, description, background } = currentSplash; const isLastPage = index === splashs.length - 1; const isFirstPage = index === 0; return ( <Row> <Col xs={24}> <section className={`${isFirstPage ? bg : BgGradiant} ${splash}`}> {/* 非首页渲染背景图 */} {!isFirstPage && ( <div className={backgroundImage}> <img src={background} alt="splash background" /> </div> )} <Container key={id} className={backgroundImage}> <div className={`${isFirstPage ? contentInner1 : contentInner2} ${contentInner}`}> {/* 首页渲染logo */} {isFirstPage && ( <div className={logo}> <img src={logoImage} alt="site logo" /> </div> )} <div className={context}> <div className={content}> <h1>{title}</h1> <p>{description}</p> </div> {/* 按钮区域 */} {isLastPage ? ( <div className={btnLogin}> <Button block onClick={goLogin}>Login</Button> </div> ) : ( <div className={btns}> <button className={btnSkip} onClick={goLogin}>skip</button> <Button onClick={handleNext}> <ArrowRightOutlined /></Button> </div> )} </div> </div> </Container> {/* 底部指示点 */} <div className={dots}> {splashs.map((_, idx) => ( <div key={idx} className={`${dot} ${index === idx ? dotActive : dotDeActive}`} /> ))} </div> </section> </Col> </Row> ) } export default Splash;
原有CSS代码无冗余问题,不需要调整
优化收益
- 去掉无意义的全量遍历,页面每次只渲染当前需要展示的单页内容,渲染性能提升
- 当前页属性仅需解构一次,JSX里直接调用,完全消除重复的
splashs[index].xxx属性访问 - 去掉重复的跳转方法,代码量精简30%左右
- 消除硬编码逻辑,后续新增/删除引导页仅需修改
splashs数组配置,不需要改动业务判断代码 - 修复原代码存在的状态更新闭包隐患、属性拼写错误、图片缺少alt属性等问题
内容的提问来源于stack exchange,提问作者h.m.p.frontendDeveloper
相关产品推荐
相关产品推荐

