我正在建立一个反应应用程序,本质上是扩大和放置一个边界周围的图像,当它被点击。下面的代码位于产品列表中每个项目的Modal组件中。在同一时间,将不会有超过6-8个图像被渲染在模式内。然而,我发现,当我只测试一个图像时,它要快得多,并且不像打开模态时有4个图像时那样滞后。因此,我想知道以下两部分代码中的任何一部分是否具有性能优势,或者是否有更好的方法:
调用以初始化模态
<ProductModal
show={this.state.isModalOpen}
onHide={() => this.setState({ isModalOpen: !this.state.isModalOpen })}
item={this.state.currentItem}
key={this.state.currentItem.id}
/>
实现1:
ProductModal的内部呈现():
<div className="d-flex flex-wrap mt-5 align-self-start ml-3">
{this.props.item.images.map((image, index) => {
if (index >= maxSelectableImages) {
return null;
} else {
return (
<img
className={`selectable-image ${
index === 0 ? "selected-border" : ""
}`}
alt="Error Loading"
src={image}
key={index}
onClick={(e) => this.updateSelectedImage(e, image)}
></img>
);
}
})}
</div>
onclick处理程序:
updateSelectedImage(event, image) {
if (this.state.prevSelectedElement) {
this.state.prevSelectedElement.classList.remove("selected-border");
} else {
// if there is no prevSelected element then by default the selected item
// always is the first image in the array as seen in the above snippet from render
**// but this means for each modal I have to call query selector once**
const firstImage = document.getElementsByClassName("selected-border")[0];
firstImage.classList.remove("selected-border");
}
event.target.classList.add("selected-border");
this.setState({ selectedImage: image, prevSelectedElement: event.target });
}
实现2:
在呈现()中:
<div className="d-flex flex-wrap mt-5 align-self-start ml-3">
{this.props.item.images.map((image, index) => {
if (index >= maxSelectableImages) {
return null;
} else if (index === 0) {
const firstItem = (
<img
className="selectable-image selected-border"
alt="Error Loading"
src={image}
key={index}
onClick={(e) => this.updateSelectedImage(e, image)}
></img>
);
**// is this dangerous? I have read it can cause infinite loops to call set state in render.**
this.setState({prevSelectedElement: firstItem});
return firstItem;
} else {
return (
<img
className="selectable-image"
alt="Error Loading"
src={image}
key={index}
onClick={(e) => this.updateSelectedImage(e, image)}
></img>
);
}
})}
</div>
处理程序:
updateSelectedImage(event, image) {
**// notice no query selector call needed now**
this.state.prevSelectedElement.classList.remove("selected-border");
event.target.classList.add("selected-border");
this.setState({ selectedImage: image, prevSelectedElement: event.target });
}
发布于 2020-05-14 06:24:52
问题是
this.setState({prevSelectedElement: firstItem});
您不应该在setState()
中使用render()
,因为如果状态更改,setState()
可以触发重新呈现。在您的情况下,它将触发至少一次。您还不应该将诸如firstItem
这样的react元素放到状态中。
尝试将逻辑与呈现分离开来。您应该使用selectedIndex
和prevSelectedIndex
而不是元素。
onClick={() => this.updateSelectedImage(index)}
和
updateSelectedImage(index) {
const prev= this.state.selectedIndex;
this.setState({ selectedIndex: index, prevSelectedIndex: prev});
}
https://stackoverflow.com/questions/61789934
复制相似问题