首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >react渲染的性能提升

react渲染的性能提升
EN

Stack Overflow用户
提问于 2020-05-14 05:28:09
回答 1查看 45关注 0票数 0

我正在建立一个反应应用程序,本质上是扩大和放置一个边界周围的图像,当它被点击。下面的代码位于产品列表中每个项目的Modal组件中。在同一时间,将不会有超过6-8个图像被渲染在模式内。然而,我发现,当我只测试一个图像时,它要快得多,并且不像打开模态时有4个图像时那样滞后。因此,我想知道以下两部分代码中的任何一部分是否具有性能优势,或者是否有更好的方法:

调用以初始化模态

代码语言:javascript
运行
复制
 <ProductModal
          show={this.state.isModalOpen}
          onHide={() => this.setState({ isModalOpen: !this.state.isModalOpen })}
          item={this.state.currentItem}
          key={this.state.currentItem.id}
        />

实现1:

ProductModal的内部呈现():

代码语言:javascript
运行
复制
<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处理程序:

代码语言:javascript
运行
复制
      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:

在呈现()中:

代码语言:javascript
运行
复制
<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>

处理程序:

代码语言:javascript
运行
复制
  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 });
  }
EN

回答 1

Stack Overflow用户

发布于 2020-05-14 06:24:52

问题是

代码语言:javascript
运行
复制
this.setState({prevSelectedElement: firstItem});

您不应该在setState()中使用render(),因为如果状态更改,setState()可以触发重新呈现。在您的情况下,它将触发至少一次。您还不应该将诸如firstItem这样的react元素放到状态中。

尝试将逻辑与呈现分离开来。您应该使用selectedIndexprevSelectedIndex而不是元素。

代码语言:javascript
运行
复制
onClick={() => this.updateSelectedImage(index)}

代码语言:javascript
运行
复制
updateSelectedImage(index) {
    const prev= this.state.selectedIndex;
    this.setState({ selectedIndex: index, prevSelectedIndex: prev});
}   
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61789934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档