美文网首页
React 之性能优化

React 之性能优化

作者: PoWerfulHeart | 来源:发表于2018-08-23 16:25 被阅读32次

    一.包含父子组件的Tab切换

    当我们将tab切换分离到子组件时很多人喜欢这样写
    父组件:

    class App extends Component{
      constructor(props){
        super(props);
        this.state = {
        };
        this.type = 0;
      }
    
     tabSwitch(){
         this.setState({
               //change state
         })
     }
    
      render(){
        return (
              <Tab renderFun={this.tabSwitch} type={this.type}  />
        )
      }
    } 
    
    ReactDOM.render(
        <App />,
        document.getElementById('root')
    )
    

    子组件:

    export default class Tab extends Component{
        constructor(props){
          super(props);
          this.state = {
            tab:['tab1','tab2'],
            current:this.props.type
          };
        }
    
        tabSwitch(index){
          this.setState({
            current:index
          },() => {
            this.props.renderFun(this.state.current);
          })
        }
    
        render(){
        var _this = this;
        return (
           <div className='tab'>
               { this.state.tab.map(function(ele,index){
                        return <div key={index} className={'tab_' + index + ' ' + (_this.state.current == index ? 'tab_active':'')} onClick={_this.tabSwitch.bind(_this,index)}>{ele}</div>
                 })
               }
           </div>
        )
      }
    }
    

    这样的写法实现功能是没问题。当我们切换tab时,将点击的tab栏目传递给父组件,父组件改变state去重新渲染tab列表。但是这里虽然功能实现,但是这样会有重复渲染的问题出现。

    组件更新过程:shouldComponentUpdate=》componentWillUpdate-》render-》componentDidUpdate

    我们在子组件点击的时候,setState改变了current,子组件重新渲染,然后回调点击的tab给父组件,父组件执行setState会开始更新过程,这时候父组件的shouldComponentUpdate未设置,默认是true,父组件完成了更新过程,由于父组件的渲染,所以子组件也开始更新过程,此时shouldComponentUpdate也是true,子组件也会完成更新过程。子组件相当于重复渲染了一次

    正确的写法:

    React建议将关系到渲染的数据保存在state中。这里能勾关系到渲染的就是这个type了。因为type的改变会导致我们的列表改变
    父组件:

    class App extends Component{
      constructor(props){
        super(props);
        this.state = {
              type:0
        };
      }
    
     tabSwitch(index){
         this.setState({
              type:index
         })
     }
    
      render(){
        return (
              <Tab renderFun={this.tabSwitch} type={this.state.type}  />
        )
      }
    } 
    
    ReactDOM.render(
        <App />,
        document.getElementById('root')
    )
    

    子组件:

    export default class Tab extends Component{
        constructor(props){
          super(props);
          this.state = {
            tab:['tab1','tab2'],
          };
              this.current = this.props.type;
        }
    
           shouldComponentUpdate(newProps, newState) {
            return newProps.type !== this.props.type;    //此时返回false,子组件不会被重复渲染
        }
    
        tabSwitch(index){
         this.current = index;
         this.props.renderFun(index);
        }
    
        render(){
        var _this = this;
        return (
           <div className='tab'>
               { this.state.tab.map(function(ele,index){
                        return <div key={index} className={'tab_' + index + ' ' + (_this.current == index ? 'tab_active':'')} onClick={_this.tabSwitch.bind(_this,index)}>{ele}</div>
                 })
               }
           </div>
        )
      }
    }
    

    相关文章

      网友评论

          本文标题:React 之性能优化

          本文链接:https://www.haomeiwen.com/subject/dukmiftx.html