如何用useState&useEffect切换组件显示?Next.js长分类代码优化
优化车辆分类切换组件的方案
核心优化:移除冗余状态与副作用
你原来的多个useState(cars/bikes等)和useEffect完全是冗余的——只需要维护selectedCategory这一个状态,直接用它判断要渲染的组件即可,无需额外同步多个状态。
用配置化方式实现可扩展的分类管理
把分类信息抽象成配置数组/对象,新增分类时只需在配置里加一项,不用修改渲染逻辑,彻底解决代码冗余问题。
优化后的完整代码(配置数组版)
import Cars from './Cars'; import Bikes from './Bikes'; import Motorcycles from './Motorcycles'; import Scooters from './Scooters'; import { useState } from 'react'; const Vehicles = () => { const [selectedCategory, setSelectedCategory] = useState("cars"); // 统一管理分类的标识、显示名称和对应组件 const categoryConfig = [ { key: "cars", label: "Cars", Component: Cars }, { key: "bikes", label: "Bikes", Component: Bikes }, { key: "motorcycles", label: "Motorcycles", Component: Motorcycles }, { key: "scooters", label: "Scooters", Component: Scooters }, ]; return ( <div> {/* 遍历配置生成切换按钮 */} <div> {categoryConfig.map(({ key, label }) => ( <button key={key} onClick={() => setSelectedCategory(key)} {/* 可选:给当前选中按钮加高亮样式 */} style={{ backgroundColor: selectedCategory === key ? '#e0e0e0' : 'transparent' }} > {label} </button> ))} </div> {/* 渲染当前选中的分类组件 */} <div> {categoryConfig.find(item => item.key === selectedCategory)?.Component && ( <categoryConfig.find(item => item.key === selectedCategory).Component /> )} </div> </div> ); }; export default Vehicles;
简化版:对象映射实现快速匹配
如果觉得数组find有点冗余,可以用对象映射直接定位组件:
import Cars from './Cars'; import Bikes from './Bikes'; import Motorcycles from './Motorcycles'; import Scooters from './Scooters'; import { useState } from 'react'; const Vehicles = () => { const [selectedCategory, setSelectedCategory] = useState("cars"); // 组件与分类标识的映射表 const categoryComponents = { cars: Cars, bikes: Bikes, motorcycles: Motorcycles, scooters: Scooters, }; // 分类标识与显示名称的映射表 const categoryLabels = { cars: "Cars", bikes: "Bikes", motorcycles: "Motorcycles", scooters: "Scooters", }; const CurrentComponent = categoryComponents[selectedCategory]; return ( <div> <div> {Object.entries(categoryLabels).map(([key, label]) => ( <button key={key} onClick={() => setSelectedCategory(key)} style={{ backgroundColor: selectedCategory === key ? '#e0e0e0' : 'transparent' }} > {label} </button> ))} </div> {CurrentComponent && <CurrentComponent />} </div> ); }; export default Vehicles;
其他可选方案
- Next.js 路由集成:如果希望每个分类对应独立URL(比如
/vehicles/cars),可以用Next.js动态路由(pages/vehicles/[category].js),通过URL参数控制显示分类,还支持页面刷新、书签分享。 - useReducer(可选):如果后续分类逻辑变得复杂(比如批量更新、异步数据处理),可以用
useReducer管理状态,但当前场景下属于过度设计。
内容的提问来源于stack exchange,提问作者Mintee
相关产品推荐
相关产品推荐

