如何在React.js中按JSON的room_name字段排序并分组展示设备
按房间分组展示家居设备的React实现方案
核心思路
先将所有类型的设备合并为统一数组,再按room_name分组,最后排序房间并以Bootstrap卡片形式渲染每组设备。
1. 重构状态与数据处理
替换原有的多设备状态,改用单状态存储分组后的数据,在获取数据时完成合并、分组、排序操作:
import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { useCookies } from 'react-cookie'; // 需提前安装react-cookie包 const DiscoverCondoRoom = () => { const [devicesByRoom, setDevicesByRoom] = useState({}); const [sortedRooms, setSortedRooms] = useState([]); const [cookies] = useCookies(['accesstoken']); // 获取登录token const getDevices = async () => { try { const result = await axios.get('https:/xxx.com/discover', { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${cookies.accesstoken}` }, }); // 步骤1:合并所有设备并添加类型标识 const allDevices = []; Object.entries(result.data.attributes).forEach(([type, devices]) => { devices.forEach(device => { allDevices.push({ ...device, deviceType: type // 标记设备类型(camera/light/climate等) }); }); }); // 步骤2:按room_name分组 const grouped = allDevices.reduce((acc, device) => { const room = device.room_name || 'Unassigned'; if (!acc[room]) { acc[room] = []; } acc[room].push(device); return acc; }, {}); // 步骤3:对房间名称排序(忽略大小写) const sortedRoomNames = Object.keys(grouped).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()) ); setDevicesByRoom(grouped); setSortedRooms(sortedRoomNames); } catch (err) { console.error('获取设备失败:', err); } }; useEffect(() => { getDevices(); }, []); // 渲染部分 return ( <div className="container mt-4"> {sortedRooms.map(roomName => ( <div key={roomName} className="mb-4"> {/* 房间卡片头部 */} <div className="card"> <div className="card-header bg-primary text-white"> <h5>{roomName}</h5> </div> {/* 房间设备列表 */} <div className="card-body"> <div className="row"> {devicesByRoom[roomName].map(device => ( <div key={device.entity_id} className="col-md-4 mb-3"> <div className="card h-100"> <div className="card-body"> <h6 className="card-title">{device.entity_id}</h6> <p className="card-text"> <strong>类型:</strong> {device.deviceType}<br/> {device.object_id && <><strong>设备ID:</strong> {device.object_id}<br/></>} {device.state && <><strong>状态:</strong> {device.state}</>} </p> </div> </div> </div> ))} </div> </div> </div> </div> ))} </div> ); }; export default DiscoverCondoRoom;
关键说明
- 设备合并:通过
Object.entries遍历所有设备类型,为每个设备添加deviceType字段,方便后续区分展示。 - 分组逻辑:使用
reduce方法将设备按房间名聚合,无房间名的设备默认归为"Unassigned"分组。 - 房间排序:用
localeCompare实现不区分大小写的字母排序,保证展示顺序统一。 - Bootstrap布局:利用
container、row、col-md-4实现响应式卡片布局,每个设备为独立小卡片,房间为大卡片包裹。
内容的提问来源于stack exchange,提问作者user15346124
相关产品推荐
相关产品推荐

