React 无状态组件 - 性能和 PureRender

React Stateless components - performance and PureRender

大家都说使用stateless组件会提高应用性能。然而,我注意到,在错误的地方使用无状态组件确实会降低 应用程序性能。

发生这种情况是因为无状态组件始终呈现,即使属性没有改变

stateful 组件的情况下,我们可以使用 PureComponentPureRenderMixin 或实现自己的 shouldComponentUpdate - 感谢它注意到 大增加 与无状态组件相比,应用程序性能。

我想问一下是否有某种方法可以为无状态组件实现类似 pureRender 的东西?。我对在有状态组件中包装无状态组件不感兴趣。

如果这不可能,那么 stateless 组件中的 性能 究竟如何?

我准备了两个简单的例子,展示我写的东西。尝试更改活动按钮:

有状态的 PureComponent:

class List extends React.Component{
  constructor(props) {
    super(props);
    this.generateElements = this.generateElements.bind(this);
    this.changeActive = this.changeActive.bind(this);
    this.state = {
     active: 0
    }
  }
 generateElements(){
   let elements = [];
    for(let i = 0; i<=1000; i++){
     elements.push(<Element key={i} 
                  index={i}
                             active={this.state.active === i} 
                             changeActive={this.changeActive} /> )
    }
    return elements;
  }
  changeActive(index){
   this.setState({
     active: index
    });
  }
  render() {
    return (
     <div>
        <div className="classButtons">
          {this.generateElements()}
        </div>
      </div>
    )
  }
}

class Element extends React.PureComponent{
  render() {
  console.log('render');
    return(
      <button onClick={this.props.changeActive.bind(null, this.props.index)}
            className={this.props.active ? 'active' : null} >
       Element {this.props.index}
      </button>
    )

  }
}

ReactDOM.render(<List />, document.getElementById('container'));
button{
  display: block;
  margin-bottom: 2px;
}
button.active{
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>

<div id="container"></div>

无状态组件:

class List extends React.Component{
  constructor(props) {
    super(props);
    this.generateElements = this.generateElements.bind(this);
    this.changeActive = this.changeActive.bind(this);
    this.state = {
     active: 0
    }
  }
 generateElements(){
   let elements = [];
    for(let i = 0; i<=1000; i++){
     elements.push(<Element key={i} 
                  index={i}
                             active={this.state.active === i} 
                             changeActive={this.changeActive} /> )
    }
    return elements;
  }
  changeActive(index){
   this.setState({
     active: index
    });
  }
  render() {
    return (
     <div>
        <div className="classButtons">
          {this.generateElements()}
        </div>
      </div>
    )
  }
}

const Element = ({changeActive, index, active}) => {
 console.log('render');
  return(
    <button onClick={changeActive.bind(null, index)}
            className={active ? 'active' : null} >
            Element {index}
    </button>
  )
}

ReactDOM.render(<List />, document.getElementById('container'));
button{
  display: block;
  margin-bottom: 2px;
}
button.active{
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>

<div id="container"></div>

I noticed, however, that the use of stateless component in the wrong place can really reduce application performance.

确实如此。对于复杂的组件,你应该避免使用无状态组件。

Everyone says that it uses stateless components will improve application performance

您错过了一个重要的部分...在未来

I wanted to ask if there is some way to implementation something like pureRender for stateless component?

不,还没有。

If this is not possible, so how is it really with performance in stateless components?

实施 shouldComponentUpdate 的组件性能会更好。


请参阅 here React 团队支持的我的声明。那里的两个重要引述

For complex components, defining shouldComponentUpdate (eg. pure render) will generally exceed the performance benefits of stateless components.

Dan Abramov:

There are currently no special optimizations done for functions, although we might add such optimizations in the future. But for now, they perform exactly as classes.