停止重新渲染现有组件

时间:2019-11-19 07:52:24

标签: javascript reactjs

我有一个组件,例如<Test /> 我在页面上多次调用此组件,每次都是通过将src更改为随机数(例如/images/1.jpg)来更改其图片。这没问题,我的问题是,当我渲染新组件时,它会更改其随机图像,但还会重新渲染页面上已经存在的该组件的所有实例,以再次更改其图像。

有没有办法我只能更新组件的最新版本而无需重新呈现现有组件?

class App extends React.Component {

  state = {
    items: Array.from({ length: 5 })
  };

  fetchMoreData = () => {
      this.setState({
        items: this.state.items.concat(Array.from({ length: 5 }))
      });
  };

  render(){
    return (
      <div className="App">
        <header className="App-header">
          <p>
            Infinite Scrolling Goats
            <span className="small-text">
              (Not Infinite Scrotes, sorry)
            </span>
          </p>
          <img src={logo} className="App-logo" alt="logo" />
          </header>
          <Toggle>
          <InfiniteScroll
            dataLength={this.state.items.length}
            next={this.fetchMoreData}
            hasMore={true}
            loader={<h4>Loading...</h4>}
          >
            {this.state.items.map((i, index) => (
            <Goat />
          ))}
          </InfiniteScroll>
          </Toggle>
      </div>
    );
  }
  }

是我的app.js,被称为以下组件

class Goat extends Component {

    render(){

        const arNames = [
            'Napoleon',
            'Albert',
            'Phil',
            'George',
            'Graham',
            'Bertie',
            'Dexter',
            'Frankie',
            'Tommy',
            'Kyle',
            'Jacko',
            'Freddy',
            'Jezza',
            'Stepho',
          ];

        var rand = Math.floor((Math.random() * 100) + 1);
        let randomName = arNames[Math.floor(Math.random()*arNames.length)];

        return(

            <div className="GoatItem" onScroll={this.handleScroll}>
                <img className="GoatImg" src={ "/images/goats/" + rand + ".jpg" }/>
                <div className="GoatContent">
                    <p>Name: {randomName}</p>
                </div>
            </div>
        );
    }
}

参考:https://lukes-code-infinitescroats.netlify.com

1 个答案:

答案 0 :(得分:0)

Goat组件的实现中,我可以看到它只是一个静态组件,不会因属性更改而更改。因此,您可以执行以下操作:

class Goat extends Component {
    shouldComponentUpdate(nextProps){
        return false;
    }

    render(){

        const arNames = [
            'Napoleon',
            'Albert',
            'Phil',
            'George',
            'Graham',
            'Bertie',
            'Dexter',
            'Frankie',
            'Tommy',
            'Kyle',
            'Jacko',
            'Freddy',
            'Jezza',
            'Stepho',
          ];

        var rand = Math.floor((Math.random() * 100) + 1);
        let randomName = arNames[Math.floor(Math.random()*arNames.length)];

        return(

            <div className="GoatItem" onScroll={this.handleScroll}>
                <img className="GoatImg" src={ "/images/goats/" + rand + ".jpg" }/>
                <div className="GoatContent">
                    <p>Name: {randomName}</p>
                </div>
            </div>
        );
    }
}

现在,如果组件稍后接受某些道具,例如image,则将return false替换为return this.props.image === nextProps.image。这样可以确保仅在image属性更改时组件才会重新渲染。

但是我建议不要进行此优化,因为此组件的DOM树很小。因此,即使组件重新渲染,虚拟DOM差异也将非常快。在执行此操作之前,请使用开发工具验证性能滞后。