我想在Array.map
完成其循环时,不逐批将数组中的项目逐个添加到DOM。
我该怎么办?
<div className="gallery-content">
<div className="content-to-display">
{iconsToDisplay
.map((icon, index) =>
<GalleryItem
key={index}
index={index}
item={icon}
size={iconSize}
isSelected={index===selectedIconIndex}
onClick={this.setIconIndex}/>)}
</div>
</div>
答案 0 :(得分:1)
我认为一种方便的方法是先渲染加载微调器或占位符,然后在componentDidMount中的某个位置执行大量数据提取。
通过这种方式,您不必做任何延迟或手动调用appendChild
,因为最初甚至可以快速渲染大量组件。
UPD:例如,请参见此jsfiddle。首先,用非常快的初始loading...
消息来呈现画廊项目,然后我在componentDidMount
内部模拟了沉重的负载,该状态已经用“已加载”的内容更新了状态,而React已经成功重新呈现它们。
答案 1 :(得分:0)
也许这样的事情可能有用: https://react-bootstrap.github.io/react-overlays/#portals
您可以将其视为声明性的appendChild()或jQuery的 $ .fn.appendTo()。组件的子代将被追加 到指定的容器。
答案 2 :(得分:0)
以下是一种替代方法:
您可以使索引和项目保持状态,并在每次渲染之前将项目添加到列表中,而不是在JSX中循环。像这样:
state = {
index: 0,
galleryItems: []
}
componentDidMount() {
// manually triggers the first component update
this.setState({ state: this.state });
}
componentDidUpdate() {
let galleryItems = this.state.galleryItems
let index = this.state.index
// loops until it reaches to the end of list
if(index < iconsToDisplay.length - 1) {
galleryItems.push(
<GalleryItem
key={index}
index={index}
item={icon}
size={iconSize}
isSelected={index===selectedIconIndex}
onClick={this.setIconIndex}/>)})
this.setState({
index: index + 1,
galleryItems: galleryItems
})
}
}
然后,您可以在render()
周期中呈现此列表。像这样:
render() {
return(
<div className="content-to-display">
{ this.state.galleryItems }
</div>
)
}
这样,您就可以将它们一一渲染。
免责声明:我觉得这可能有效,但是我没有尝试过代码。我也怀疑它是否会以任何方式提高性能。我只是说这是一种可能的方法,也许值得一试。
答案 3 :(得分:0)
尝试使用计时器。请查看是否有帮助
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends Component {
constructor() {
super();
this.icons = [100, 200, 201, 400, 401, 404, 500, 502, 503, 504];
this.state = {
iconsToPlot: [],
message: "Rendering images...",
pendingCount: this.icons.length
};
let timerHandle = setInterval(() => {
let imgNo = this.icons.pop();
if (imgNo) {
let pendingCount = this.icons.length;
this.setState({
iconsToPlot: [...this.state.iconsToPlot, imgNo],
pendingCount: pendingCount
});
} else {
clearInterval(timerHandle);
this.setState({ message: "Timer stoped as all images are rendered." });
}
}, 3000);
}
render() {
return (
<div>
<p>
{this.state.message} Remaining {this.state.pendingCount} images{" "}
</p>
<ul>
{this.state.iconsToPlot.map((key, index) => (
<li key={index}>
<img src={`https://http.cat/${key}`} width="150" />
</li>
))}
</ul>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
播放here