当前位置: 首页 > news >正文

【React + TypeScript 实现高性能多列多选组件】

引言

在现代Web应用中,多选组件是常见的UI元素,尤其是在需要用户从多个选项中进行选择的场景。本文将介绍如何使用React和TypeScript实现一个功能完整、性能优化的多列多选组件,支持"Select All"功能和垂直填充的多列布局。

组件功能介绍

本文实现的MultiCheck组件具有以下功能:

  1. 基础多选功能:支持用户选择多个选项
  2. "Select All"功能:一键全选/取消全选所有选项
  3. 多列布局:支持垂直填充的多列排列
  4. 受控组件设计:支持外部控制选中状态
  5. 性能优化:使用React Hooks优化渲染性能
  6. 类型安全:完整的TypeScript类型定义

技术栈

  • React 18:使用函数组件和Hooks
  • TypeScript:提供类型安全
  • CSS Grid:实现灵活的多列布局
  • React HooksuseState,useEffect,useCallback

核心实现

1. 类型定义

首先,我们定义组件的类型,确保类型安全:

exporttypeOption={label:string,value:string}typeProps={label?:string,options:Option[],columns?:number,values?:string[]onChange?:(options:Option[])=>void,}

2. 状态管理

使用useState钩子管理选中状态,并通过useEffect实现与外部状态的同步:

const[selectedValues,setSelectedValues]=useState<string[]>(values);// 监听外部values变化,实现双向更新useEffect(()=>{setSelectedValues(values);},[values]);

3. 全选功能实现

实现"Select All"功能需要以下逻辑:

// 判断是否全选constisAllSelected=options.length>0&&selectedValues.length===options.length;// 处理全选事件consthandleSelectAllChange=useCallback(()=>{constnewSelected=isAllSelected?[]:options.map(opt=>opt.value);setSelectedValues(newSelected);if(onChange){constselectedOptions=isAllSelected?[]:[...options];onChange(selectedOptions);}},[options,isAllSelected,onChange]);

4. 多列垂直填充布局

使用CSS Grid实现垂直填充的多列布局:

<div className='div-option-container'style={{display:'grid',gridTemplateColumns:`repeat(${Math.min(columns,options.length+1)}, auto)`,gridTemplateRows:`repeat(${Math.ceil((options.length+1)/columns)}, auto)`,gridAutoFlow:"column",// 关键:实现垂直填充width:'100%'}}>{/* 选项内容 */}</div>

5. 性能优化

使用useCallback缓存事件处理函数,避免不必要的重新渲染:

consthandleOptionChange=useCallback((value:string)=>{setSelectedValues(prev=>{constnewSelected=prev.includes(value)?prev.filter(v=>v!==value):[...prev,value];if(onChange){constselectedOptions=options.filter(opt=>newSelected.includes(opt.value));onChange(selectedOptions);}returnnewSelected;});},[options,onChange]);

完整组件代码

import'./MultiCheck.css';importReact,{useState,useEffect,useCallback}from'react';exporttypeOption={label:string,value:string}typeProps={label?:string,options:Option[],columns?:number,values?:string[]onChange?:(options:Option[])=>void,}constMultiCheck:React.FunctionComponent<Props>=({label,options,columns=1,values=[],onChange}):JSX.Element=>{const[selectedValues,setSelectedValues]=useState<string[]>(values);useEffect(()=>{setSelectedValues(values);},[values]);constisAllSelected=options.length>0&&selectedValues.length===options.length;consthandleSelectAllChange=useCallback(()=>{constnewSelected=isAllSelected?[]:options.map(opt=>opt.value);setSelectedValues(newSelected);if(onChange){constselectedOptions=isAllSelected?[]:[...options];onChange(selectedOptions);}},[options,isAllSelected,onChange]);consthandleOptionChange=useCallback((value:string)=>{setSelectedValues(prev=>{constnewSelected=prev.includes(value)?prev.filter(v=>v!==value):[...prev,value];if(onChange){constselectedOptions=options.filter(opt=>newSelected.includes(opt.value));onChange(selectedOptions);}returnnewSelected;});},[options,onChange]);return(<div className='div-container'style={{width:`${200*columns}px`}}>{label&&<div className='div-label-container'>{label}</div>}<div className='div-option-container'style={{display:'grid',gridTemplateColumns:`repeat(${Math.min(columns,options.length+1)}, auto)`,gridTemplateRows:`repeat(${Math.ceil((options.length+1)/columns)}, auto)`,gridAutoFlow:"column",width:'100%'}}><div className='div-option'><input type="checkbox"id="select-all"checked={isAllSelected}onChange={handleSelectAllChange}/><label htmlFor="select-all">Select All</label></div>{options.map(option=>(<div key={option.value}className='div-option'><input type="checkbox"id={`option-${option.value}`}checked={selectedValues.includes(option.value)}onChange={()=>handleOptionChange(option.value)}className='div-option-checkbox'/><label htmlFor={`option-${option.value}`}>{option.label}</label></div>))}</div></div>)}exportdefaultMultiCheck;

使用示例

importReactfrom'react';importMultiCheck,{Option}from'./MultiCheck';constApp:React.FC=()=>{constoptions:Option[]=[{label:'选项1',value:'1'},{label:'选项2',value:'2'},{label:'选项3',value:'3'},{label:'选项4',value:'4'},{label:'选项5',value:'5'},{label:'选项6',value:'6'},];consthandleChange=(selectedOptions:Option[])=>{console.log('选中的选项:',selectedOptions);};return(<div className="App"><MultiCheck label="多选组件示例"options={options}columns={2}values={['2','4']}onChange={handleChange}/></div>);};exportdefaultApp;

性能优化关键点

  1. 使用useCallback缓存事件处理函数:避免每次渲染都创建新函数
  2. 使用CSS Grid实现高效布局:减少JavaScript计算负担
  3. 合理设计依赖数组:确保Hooks只在必要时重新执行
  4. 函数式状态更新:避免闭包陷阱,确保基于最新状态更新

总结

本文实现的MultiCheck组件是一个功能完整、性能优化的多选组件,支持"Select All"功能和垂直填充的多列布局。通过使用React Hooks和TypeScript,我们实现了一个类型安全、性能优异的组件。

该组件的设计思路和实现方式可以作为开发其他复杂UI组件的参考,尤其是在需要处理大量选项和复杂布局的场景。

扩展建议

  1. 添加搜索功能:支持在大量选项中快速搜索
  2. 支持分组:实现选项的分组显示
  3. 添加键盘导航:提高可访问性
  4. 支持自定义样式:允许外部自定义组件样式
  5. 添加动画效果:提升用户体验

通过不断扩展和优化,这个组件可以适应更多复杂的业务场景,成为一个功能强大的多选组件库。

http://www.jsqmd.com/news/290411/

相关文章:

  • 常见的java线程并发安全问题八股
  • HTML网页仿写实验
  • Java毕设项目推荐-基于SpringBoot+Vue 学生宿舍管理系统平台Web的学生宿舍管理系统【附源码+文档,调试定制服务】
  • Node.js 用 process.cpuUsage 监控CPU使用率
  • GBDT 回归任务生成过程(逐步计算演示)
  • XGBoost 生成过程详解
  • 鸿蒙Flutter三方库适配指南:08.联合插件编写
  • 基于Android的智能健身助手APP(源码+lw+部署文档+讲解等)
  • 基于Android的智能旅游管家的设计与实现(源码+lw+部署文档+讲解等)
  • 基于Java+SSM的电子商务平台的设计与实现(源码+lw+部署文档+讲解等)
  • 基于Java+SSM的短剧推荐系统设计与实现(源码+lw+部署文档+讲解等)
  • Abaqus计算加速全解析——从算力瓶颈到高效解决方案的核心逻辑
  • Python中的Statsmodels:统计建模与假设检验
  • 《AI元人文:悟空而行》的作者说明
  • 【更新至2024年】2013-2024年上市公司迪博内部控制指数及分项指数数据
  • Java毕设选题推荐:基于JavaWeb寝室管理系统基于Web的学生宿舍管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 计算机Java毕设实战-基于Web的学生宿舍管理系统基于Java+Jsp+SpringMVC+Mysql实现的Java Web学生宿舍管理系统设【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 扫描枪测试 工业读码器
  • Java计算机毕设之基于Web的学生宿舍管理系统JavaWeb寝室管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 【课程设计/毕业设计】基于JavaWeb寝室管理系统Web的学生宿舍管理系统【附源码、数据库、万字文档】
  • 树状数组
  • go gin 入门教程,蛮不错的
  • Cursor 中优雅使用 Agent Skills:从 0 到一套可复用的“技能系统”
  • 智能体设计模式全景总结:21个模式快速串联指南
  • Java毕设项目:基于Web的学生宿舍管理系统(源码+文档,讲解、调试运行,定制等)
  • 【毕业设计】基于Web的学生宿舍管理系统(源码+文档+远程调试,全bao定制等)
  • 快来看看吧
  • 破茧成蝶:DevOps流水线测试环节的效能跃迁之路 - 教程
  • [翻译][AlexNet 原文] ImageNet Classification with Deep Convolutional Neural Networks
  • 导师推荐10个AI论文写作软件,本科生轻松搞定毕业论文!