ReactJS中多分支if语句的优化方案咨询
React多分支条件判断优化方案
核心问题分析
你的代码存在大量重复逻辑:每个类型分支都执行几乎相同的过滤和状态更新操作,同时还存在React状态更新异步性导致的bug(比如setCosmeticslength(cosmeticsall.length)中,cosmeticsall是更新前的旧值,无法得到正确长度)。
优化方案一:抽离过滤逻辑,消除重复分支
直接通过统一的条件计算过滤结果,无需逐个类型写分支:
// 定义所有需要匹配的类型列表 const VALID_TYPES = ["outfit", "wrap", "banner", "spray", "emoji", "pickaxe", "glider", "loadingscreen", "emote"]; // 1. 初始化原始数据 let filteredData = res.data.data; // 2. 类型过滤:如果当前type在有效列表中,过滤对应类型 if (VALID_TYPES.includes(type)) { filteredData = filteredData.filter(item => item.type.value === type); } // 3. 搜索关键词过滤:只要搜索框有内容就执行 if (search.trim().length > 0) { filteredData = filteredData.filter(item => item.name.includes(search)); } // 4. 统一更新状态(无需多次重置,直接设置最终结果) setCosmeticsall(filteredData); setCosmeticslength(filteredData.length);
优化点说明:
- 用数组
VALID_TYPES统一管理可筛选的类型,后续新增类型只需修改数组,无需新增分支 - 可合并两次
filter为一个,减少遍历次数提升性能:filteredData = filteredData.filter(item => { const matchesType = VALID_TYPES.includes(type) ? item.type.value === type : true; const matchesSearch = search.trim().length > 0 ? item.name.includes(search) : true; return matchesType && matchesSearch; }); - 避免了多次无用的
setCosmeticsall([])调用,直接计算最终结果后一次性更新状态 - 用过滤后的数组长度直接设置
cosmeticslength,解决异步状态更新导致的长度错误问题
优化方案二:简化渲染时的筛选逻辑
你提供的渲染筛选代码存在逻辑冗余(type.value === "All" || type.value!=="All"永远为true),可以简化为:
cosmeticsall .filter(item => type.value === "All" || item.type.value === type.value) .filter(item => item.name.includes(search)) .map(item => ( // 你的渲染逻辑 ))
如果要进一步提升性能,可合并两个filter为一个:
cosmeticsall .filter(item => { const matchesType = type.value === "All" || item.type.value === type.value; const matchesSearch = item.name.includes(search); return matchesType && matchesSearch; }) .map(item => ( // 你的渲染逻辑 ))
额外建议
- 如果
type的可选值是固定的,建议用枚举(比如const CosmeticType = { OUTFIT: "outfit", ... })代替字符串字面量,避免拼写错误 - 若数据量较大,可考虑使用
useMemo缓存过滤后的结果,减少重复计算:const filteredCosmetics = useMemo(() => { let data = cosmeticsall; if (VALID_TYPES.includes(type)) { data = data.filter(item => item.type.value === type); } if (search.trim().length > 0) { data = data.filter(item => item.name.includes(search)); } return data; }, [cosmeticsall, type, search]); // 渲染时直接用filteredCosmetics filteredCosmetics.map(...)
内容的提问来源于stack exchange,提问作者Alexandro Pineda
相关产品推荐
相关产品推荐

