ReactJS无法一次性展示全部数据:循环渲染仅显示最后一条求助
解决React + Firestore一次性展示所有客户端Orderbook数据的问题
我明白你的问题了——你现在的代码每次循环都会替换state里的orderbook,导致React反复重新渲染,最后只显示最后一个客户端的数据。咱们来一步步修复这个问题:
问题根源分析
- 重复覆盖state:每次循环里你执行
this.setState({ orderbook: orderbook }),这会把之前存储的订单数据完全替换成当前客户端的数据,所以最后只剩最后一次循环的结果。 - 冗余的Firestore请求:你在循环里反复调用
db.collection('Orderbook').get(),这会多次请求整个集合,既浪费资源又没必要。
修复方案
我们需要先一次性获取所有Orderbook数据,然后把所有客户端的订单合并到一个数组里,最后一次性更新state,这样React只会渲染一次,展示所有数据。
修改后的代码如下:
import React, { Component } from 'react'; import './App.css'; import { Card, CardImg, CardText, CardBody, CardTitle, CardSubtitle, Button } from 'reactstrap'; import Image from 'react-image-resizer'; import * as firebase from 'firebase'; class App extends Component { constructor(props) { super(props); this.state = { orderbook: [] // 初始化空数组,避免渲染时undefined报错 }; } async getOrderbookData() { try{ const db = firebase.firestore(); // 只请求一次Firestore集合,获取所有文档数据 const querySnapshot = await db.collection('Orderbook').get(); const allOrderbookDocs = []; querySnapshot.forEach(doc => { allOrderbookDocs.push(doc.data()); }); const clientArray = ['Client1', 'Client2', 'Client3', 'Client4', 'Client5', 'Client6', 'Client7']; const allOrders = []; // 遍历客户端数组,收集对应索引的订单数据 for (let i = 0; i < clientArray.length; i++) { // 确保索引不越界(避免集合中文档数量不足的情况) if (allOrderbookDocs[i] && allOrderbookDocs[i].body) { // 如果body是数组,就展开合并到allOrders;如果是单个对象,直接push if (Array.isArray(allOrderbookDocs[i].body)) { allOrders.push(...allOrderbookDocs[i].body); } else { allOrders.push(allOrderbookDocs[i].body); } } } // 一次性更新state,把所有订单数据存进去 this.setState({ orderbook: allOrders }); }catch (err) { console.error("获取Orderbook数据出错:", err); } } async componentDidMount() { // 注意:你原来调用的getMarginData()没有定义,记得补充或者移除 // this.getMarginData(); this.getOrderbookData(); } render() { return ( <div className = "App" > <Image src={ require('./investsaathilogo.png')} height = {100} width = {100}/> <h2> Orderbook Data </h2> <h5 className="container"> {this.state.orderbook.map((order, key) => <div key={key}> {/* 用key作为唯一标识更稳妥,避免order重复导致的警告 */} <li>BuySell: {order.BuySell}</li> </div> )} </h5> </div> ); } } export default App;
关键改进点
- 单次Firestore请求:只调用一次
db.collection('Orderbook').get(),获取所有文档数据,减少网络请求。 - 合并所有订单数据:创建
allOrders数组,把每个客户端的body数据合并进去(如果是数组就展开,单个对象就直接添加)。 - 一次性更新state:最后只执行一次
setState,把合并后的所有订单数据存入state,确保React一次性渲染所有内容。 - 初始化state:在constructor里把
orderbook初始化为空数组,避免渲染时因为undefined导致的报错。 - 优化key值:渲染列表时用
key作为唯一标识,避免React的列表渲染警告。
这样修改后,你的组件就会一次性展示所有客户端的Orderbook数据,不会再逐个渲染最后只保留最后一条了。
内容的提问来源于stack exchange,提问作者Prashanth Raj
相关产品推荐
相关产品推荐

